As the title says...
I have a method like so that takes HTML and returns a PDF:
private static Stream ConvertToPdf(string htmlFileContent)
{
var htmlProvider = new HtmlFormatProvider();
var htmlDocument = htmlProvider.Import(htmlFileContent);
var pdfProvider = new PdfFormatProvider();
var pdfMemoryStream = new MemoryStream();
pdfProvider.Export(htmlDocument, pdfMemoryStream);
pdfMemoryStream.Position = 0;
return pdfMemoryStream;
}
This method works perfectly on my local Windows dev box, but when I run it in a Fargate container in AWS ECS, I get the following exception if the HTML contains an image:
System.NotSupportedException: Not supported image format.
at Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource.DoOnUnknownData(Byte[] unknownData, ImageQuality imageQuality, Action`1 doOnEncodedData)
at Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource.InitializeImageInfoFromUnknownData(Byte[] unknownData, ImageQuality imageQuality)
at Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource.EnsureImageInfo()
at Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource.get_Width()
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.Objects.ImageXObject.CopyPropertiesFrom(IPdfExportContext context, ImageSource imageSource)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.PdfExportContext.GetResource(ImageSource resource)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.PdfContentExportContext.GetResource(ImageSource imageSource)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.ContentElementWriters.ImageWriter.WriteOverride(PdfWriter writer, IPdfContentExportContext context, Image element)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.ContentElementWriters.MarkableContentElementWriter`1.Write(PdfWriter writer, IPdfContentExportContext context, Object element)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.ContentElementWriters.ClippingWriter.WriteOverride(PdfWriter writer, IPdfContentExportContext context, Clipping clipping)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.ContentElementWriters.ContentElementWriter`1.Write(PdfWriter writer, IPdfContentExportContext context, Object element)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.ContentElementWriters.ContentRootWriter.WriteOverride(PdfWriter writer, IPdfContentExportContext context, IContentRootElement element)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.ContentElementWriters.ContentElementWriter`1.Write(PdfWriter writer, IPdfContentExportContext context, Object element)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.ContentElementWriters.ContentElementWriterBase.WriteElement(PdfWriter writer, IPdfContentExportContext context, Object element)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.DocumentStructure.ContentStream.BuildContentData(IPdfExportContext context, IResourceHolder resourceHolder, IContentRootElement contentRootElement)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.DocumentStructure.Page.CopyPropertiesFrom(IPdfExportContext context, RadFixedPage fixedPage)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.DocumentStructure.DocumentCatalog.CopyRadFixedPageProperties(RadFixedPage source, Page destination, IRadFixedDocumentExportContext context)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.DocumentStructure.DocumentCatalog.CopyPagePropertiesFrom(IRadFixedDocumentExportContext context)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.DocumentStructure.DocumentCatalog.CopyPropertiesFrom(IRadFixedDocumentExportContext context)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.PdfExporter.Export(IRadFixedDocumentExportContext context, Stream output)
at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider.ExportOverride(RadFixedDocument document, Stream output)
at Telerik.Windows.Documents.Common.FormatProviders.FormatProviderBase`1.Export(T document, Stream output)
at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.PdfFormatProvider.ExportOverride(RadFlowDocument document, Stream output)
at Telerik.Windows.Documents.Common.FormatProviders.FormatProviderBase`1.Export(T document, Stream output)
Hi there,
I need to create a pdf with various different tabs. So, I work with RadPdfProcessing.
In order to create a next page when there is no more place on the current page, I set a method that measures the available size on the page (without margin) and the size of the object to draw, before drawing it. If there is enough space, I draw it on current page, if not, I create a new page and draw it on.
But when I run my code, some tables are drawn in the margin of my page, as you can see on attached pictures.
I don't understant why. And when debugging, measures are working fine...
Could someone explain me what I'm missing or doing wrong please?
Here is my code :
Code about measuring object and page creation
public static readonly Size _pageSize = new(Unit.MmToDip(210), Unit.MmToDip(297));
public static readonly Thickness _margins = new(Unit.MmToDip(15));
public static DocumentContainer CreateNewPage(RadFixedDocument document)
{
var page = document.Pages.AddPage();
var editor = new DocumentContainer(page, _pageSize, new Padding(_margins.Top, _margins.Right, _margins.Bottom, _margins.Left));
//if not first page, position the editor between margins
if(document.Pages.Count != 1)
editor.Position.Translate(_margins.Left, _margins.Top);
return editor;
}
public static DocumentContainer CheckRemainingSpaceAndCreateNewPageIfNeeded(IBlockElement elementToDraw, DocumentContainer editor, RadFixedDocument document)
{
var remainingHeight = editor.PageHeight - _margins.Bottom - editor.Position.Matrix.OffsetY;
var neededSize = elementToDraw.Measure(new Size(editor.PageInternWidth, editor.PageInternHeight));
if(remainingHeight < neededSize.Height)
{
return CreateNewPage(document);
}
return editor;
}
Code about table creation
public static Table CreateTable(BorderStyle borderStyle = BorderStyle.None)
{
return new Table
{
Borders = new TableBorders(new Border(borderStyle)),
LayoutType = TableLayoutType.FixedWidth,
};
}
And the code about table drawing
private Table DrawOneStyleTable(...)
{
var oneCellPadding = new Thickness(Unit.MmToDip(5));
var anotherCellPadding = new Thickness(Unit.MmToDip(5), Unit.MmToDip(2), Unit.MmToDip(5), Unit.MmToDip(2));
//Add table
Table table = Helper.CreateTable();
table.DefaultCellProperties.Padding = new Thickness(5);
table.Borders = new TableBorders(new Border(2, BorderStyle.Single, mycolor));
//Add rows
_editor = Helper.CheckRemainingSpaceAndCreateNewPageIfNeeded(table, _editor, _document);
_editor.DrawTable(table, _editor.PageInternWidth);
return table;
}
private Table DrawSecondStyleTable(...)
{
//Add table and row
Table table = Helper.CreateTable();
//Add content
_editor = Helper.CheckRemainingSpaceAndCreateNewPageIfNeeded(table, _editor, _document);
_editor.DrawTable(table, _editor.PageInternWidth);
return table;
}
Please do not hesitate to ask me more information if needed.
Thank you in advance for your help,
Regards,
Adrian
Dear Telerik Team,
We encounter an issue with export html data to pdf file using below code. For example,
using Telerik.Web.UI;
using OpenXmlSpreadsheet = DocumentFormat.OpenXml.Spreadsheet;
using Pdf = Telerik.Windows.Documents.Flow.FormatProviders.Pdf;
using te = Telerik.Windows.Documents.Flow.FormatProviders.Html;
using tm = Telerik.Windows.Documents.Flow.Model;
using tp = Telerik.Windows.Documents.Primitives;
using tt = Telerik.Windows.Documents.Spreadsheet.Theming;te.HtmlFormatProvider provider = new te.HtmlFormatProvider();
tm.RadFlowDocument document = provider.Import(HttpUtility.HtmlDecode(htmldata));
tt.ThemeFontScheme fs = new tt.ThemeFontScheme("Arial", "Helvetica", "sans-serif");
tt.DocumentTheme theme = new tt.DocumentTheme("PDF", document.Theme.ColorScheme, fs);
document.Theme = theme;
document.Sections[0].PageMargins = new tp.Padding(50, 25, 50, 25);
Pdf.PdfFormatProvider providerPdf = new Pdf.PdfFormatProvider();
byte[] fileBytes = providerPdf.Export(document);
"providerPdf.Export(document);" this line throws exception "An exception occurred during a WebClient request" whenever we include <img src="/image path/image.png" /> html tag.
Your support is appreciated.
Hello,
This post is not a question. I simply wanted to share my partial solution for those who may need it.
Below is a manual method for creating a Block with justified text in the PDFProcessing API. This makes use of the Block object's Measure method and the WordSpacing property to adjust each line until the indicated width is filled.
PLEASE NOTE:
Best Regards,
Aidan D.
TAGS FOR GOOGLE: Justify, Alignment
using System;
using System.Collections.Generic;
using Telerik.Windows.Documents.Fixed.Model.Editing;
using Telerik.Windows.Documents.Fixed.Model.Fonts;
classTextJustify
{
public static void InsertJustifiedBlock(FixedContentEditor PageEditor, string Text, int TextBoxWidth)
{
Block justifiedBlock = CreateJustifiedBlock(Text, TextBoxWidth, PageEditor.TextProperties.Font, PageEditor.TextProperties.FontSize);
PageEditor.DrawBlock(justifiedBlock);
}
public static Block CreateJustifiedBlock(string Text, int TextBoxWidth, FontBase Font, double FontSize)
{
Block justifiedBlock = new Block();
double currentSpacing = 0;
double spacingStep = 1;
string currentLine;
if (Text.Length > 0)
{
{
var withBlock = justifiedBlock.TextProperties;
// Default word spacing. Must be initialized to 0 before use. This defaults to Nothing/Null// and will not function correctly if not initialized.
withBlock.WordSpacing = 0;
withBlock.Font = Font;
withBlock.FontSize = FontSize;
}
// We need a seperate block to use as a measuring tool using the same text properties as the justified block.
Block measuringBlock = new Block(justifiedBlock);
// Make sure the WordSpacing property is initialized to zero. // Break the text string into lines, adding as many full words as we can to each line.// This does not support hyphenation.
List<string> lines = breakIntoLines(Text, TextBoxWidth, ref measuringBlock);
for (int i = 0; i <= lines.Count - 1; i++)
{
currentLine = lines[i];
// For all except the last line, space out the words to fill the allowed space.if (i < (lines.Count - 1))
{
do
{
// Set the word spacing before inserting the text.
measuringBlock.TextProperties.WordSpacing = currentSpacing;
// We need to reinsert the text each time the spacing changes since the spacing is only applied on insert
measuringBlock.Clear();
measuringBlock.InsertText(currentLine);
measuringBlock.Measure();
if (measuringBlock.DesiredSize.Width > TextBoxWidth && spacingStep != 0.01)
{
// Step back by one then narrow in at finer increments
currentSpacing -= spacingStep;
spacingStep /= 10;
currentSpacing += spacingStep;
continue;
}
currentSpacing += spacingStep;
}
while (measuringBlock.DesiredSize.Width > TextBoxWidth && spacingStep == 0.01);
// Reduce by one step to bring it back into allowed width
currentSpacing -= spacingStep;
}
// Add the line of text with the appropriate spacing.using (justifiedBlock.SaveTextProperties())
{
justifiedBlock.TextProperties.WordSpacing = currentSpacing;
justifiedBlock.InsertText(currentLine);
justifiedBlock.InsertLineBreak();
}
// Reset for next line
currentSpacing = 0; spacingStep = 1;
}
}
return justifiedBlock;
}
private static List<string> breakIntoLines(string Text, int maxLineWidth, ref Block measuringBlock)
{
List<string> sResults = new List<string>();
string[] lines = Text.Split(newstring[] { "\n", "\r\n" }, StringSplitOptions.None);
foreach (string line in lines)
{
string[] words = line.Split(newstring[] { " " }, StringSplitOptions.RemoveEmptyEntries);
sResults.Add(""); // Initialize the line. This may remain empty if the line is blank.for (int i = 0; i <= words.Length - 1; i++)
{
if (sResults[sResults.Count - 1].Length == 0)
sResults[sResults.Count - 1] = words[i];
else
{
string testLine = string.Concat(sResults[sResults.Count - 1], " ", words[i]);
measuringBlock.InsertText(testLine);
measuringBlock.Measure();
if (measuringBlock.DesiredSize.Width <= maxLineWidth)
// Replace with new, longer line
sResults[sResults.Count - 1] = testLine;
else// Start new line
sResults.Add(words[i]);
// Remove text from measuring block to reset for next word
measuringBlock.Clear();
}
}
}
return sResults;
}
}
Hello,
Using a RadFlowDocument, I must generate dynamic headers for columns of data. There is no template or way to know ahead of time what headers are needed, so we have to recursively extract data and render tables/rows within outer cells, to align the data w/ the proper column. Overall this works fine. However, tables do not, as far as I can tell, stretch to fit the space their cells, so I'm left with these gaps (in blue in first attached image), as the overall height of the main header row is set by the column with the largest/tallest data, in this case the group of columns with the red borders.
Is there any way to get the inner tables to stretch to fill that available height?
Note: The different color backgrounds and borders in attached image are for debugging purposes
The general structure of Cells/Rows/Tables that I end up with following this recursive build is described in the second attached image. Rows are red, cells are green, and tables are blue. Perhaps there is another way to build the header that I am not considering.
Thank you
Edit: I solved the problem changing tactics. I queried the list of headers for a maximum depth and created that number of rows. Added the rows to a list and passed the list to the recursive function. Instead of creating a new table for each subcategory, the code now just adds the item to the proper row, index based on the item's depth, and with proper RowSpan and ColumnSpan values, I'm able to get the desired placement. Image added for comparison.
Hi,
I want to set a particular cell to be 20% wide. I am using .NET MVC libraries.
My code reads as follows
using CellWidth = Telerik.Windows.Documents.Flow.Model.Styles; . . . detailsLine = table.Rows.AddTableRow(); detailsCell = detailsLine.Cells.AddTableCell(); detailsCell.PreferredWidth = new CellWidth.TableWidthUnit(CellWidth.TableWidthUnitType.Percent, 20.0);
I have an error:
CS0029: Cannot implicitly convert type 'Telerik.Windows.Documnets.Flow.Model.Styles.TableWidthUnit' to 'double?'
What can I do.
I need pdf landscape orientation.
I export document, then change size:
pdf = pdfFlowProvider.ExportToFixedDocument(doc); pdf.Pages[0].Size = new Size(1056, 816);
Problem that I have lot of space on the right side, probably because I exported document first.
But I can't change page size before this, because I don't have pages.
How to fix this?