通过 iText 创建 PDF 文档时,某些 HTML 和 CSS 样式未应用
Posted
技术标签:
【中文标题】通过 iText 创建 PDF 文档时,某些 HTML 和 CSS 样式未应用【英文标题】:Some HTML and CSS styles not applied when creating PDF document by iText 【发布时间】:2018-11-28 15:10:02 【问题描述】:我在从 html 生成 PDF 时遇到了 iText 问题。我从 Locize 传递“导入信息部分”,其中包含粗体标签和列表项目符号
<li>\n
<b>Toll-free</b> (within Canada and the USA):
<b>1.800.xxxxxxx</b>\n
</li>\n
pdf 文件在 Confirmation.cs 中生成。下面列出了从 Confirmation.cs 传递到 ImportantInformation.cs 的参数“medSrc”。不知何故,粗体样式和列表项目符号不适用于结果 pdf 文件。
我已经调试了一段时间,但仍然不知道发生了什么。有谁知道我错过了什么?
提前谢谢你!
确认.cs
...
namespace xxx.Pdf.xxx.xxx
public partial class Confirmation
private IApplication application;
public Confirmation(IApplication application)
this.application = application;
public byte[] Create()
var memoryStream = new MemoryStream();
var css = Content.Css;
//Create Document
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(memoryStream));
PageSize pageSize = PageSize.LETTER;
Document document = new Document(pdfDocument, pageSize);
Header headerHandler = new Header(document);
PageXofY footerHandler = new PageXofY(pdfDocument);
document.SetTopMargin(headerHandler.GetTableHeight());
//Assign event-handlers
pdfDocument.AddEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
pdfDocument.AddEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
...
// ======>Important Information <=======
var importantInfo = new ImportantInformation();
Table impInfoTable = importantInfo.CreateTable(
HtmlUtility.MergeCssWithHtml(css, Content.ImportantInformationEmergencyMedical),
HtmlUtility.MergeCssWithHtml(css, Content.ImportantInformationTripCancellation));
document.Add(impInfoTable).Add(new Paragraph("\n"));
//set column parameters
float offset = 36;
float columnWidth = (pageSize.GetWidth() - offset * 2 + 15) / 2;
float columnHeight = pageSize.GetHeight() - offset * 2;
float tableWidth = columnWidth - 10;
//define column area
Rectangle[] columns = new Rectangle[]
new Rectangle(offset , offset, columnWidth, columnHeight),
new Rectangle(columnWidth + 30, offset, columnWidth, columnHeight)
;
document.SetRenderer(new ColumnDocumentRenderer(document, columns));
document.Add(new AreaBreak(AreaBreakType.LAST_PAGE));
foreach (Applicant applicant in application.Applicants)
ApplicantTable applicantTable = new ApplicantTable();
Table table = applicantTable.CreateTable(applicant, tableWidth);
//Table another = applicantTable.CreateTable(application.Applicants[1], tableWidth);
document.Add(table).Add(new Paragraph("\n").SetFontSize(3));
footerHandler.WriteTotal(pdfDocument);
document.Close();
pdfDocument.Close();
var pdf = memoryStream.ToArray();
return pdf;
ImportantInformation.cs
...
namespace xxx.xxx.xxx.Pdf
public class ImportantInformation
public Table CreateTable(string medSrc, string tciSrc)
float[] colWidth = new float[] 50f, 50f ;
Table table = new Table(UnitValue.CreatePercentArray(colWidth));
table.SetWidth(new UnitValue(UnitValue.PERCENT, 100));
PdfFont avenir = FontFactory.CreateAvenirLightStandardMedium();
Paragraph title = new Paragraph().Add("**IMPORTANT INFORMATION**").SetFontSize(12).SetFont(avenir).SetBold().SetTextAlignment(TextAlignment.CENTER);
Cell titleCell = new Cell(1, 2).Add(title).SetBorder(Border.NO_BORDER);
table.AddCell(titleCell);
Cell medImportantinfo = new Cell()
.SetBorder(Border.NO_BORDER)
.Add(new Paragraph("Paragraph A")
.SetFirstLineIndent(10f)
.SetBold()
.SetFontSize(9)
.SetFont(avenir));
Cell tciImportantInfo = new Cell()
.SetBorder(Border.NO_BORDER)
.Add(new Paragraph("Paragraph B")
.SetFirstLineIndent(10f)
.SetBold()
.SetFontSize(9)
.SetFont(avenir));
IList<IElement> medInfo = HtmlToCellFormat.HtmlToElements(medSrc);
IList<IElement> tciInfo = HtmlToCellFormat.HtmlToElements(tciSrc);
foreach (IElement e in medInfo)
medImportantinfo.ElementToCell(e);
foreach (IElement e in tciInfo)
tciImportantInfo.ElementToCell(e);
table.AddCell(medImportantinfo).AddCell(tciImportantInfo);
return table;
medSrc:
<html>
<body>\n
<ul style=\"text-align: justify; list-style-type: disc; font-family: avenir, Arial, Helvetica, sans-serif; font-size: 10px\">\n
<li>\n In the event of a medical emergency contact:\n
<ul style=\"text-align: justify; list-style-type: circle; font-family: avenir, Arial, Helvetica, sans-serif; font-size: 10px\">\n
<li>\n
<b>Toll-free</b> (within Canada and the USA):
<b>1.800xxxxxx</b>\n
</li>\n
<li>\n
<b>Collect</b> (from all other locations):
<b>1.xxxxxx</b>\n
</li>\n
</ul>\n
</li>\n
...
</body>
</html>
更新: 下面是ElementToCell和HtmlToElements函数的定义
public static class HtmlToCellFormat
public static string baseUri = "/";
public static void ElementToCell(this Cell cell, IElement e)
var type = e.GetType().ToString();
if (e.GetType() == typeof(Image))
cell.Add((Image)e);
else if (e.GetType() == typeof(Paragraph) || (e.GetType() == typeof(List)))
cell.Add((IBlockElement)e);
public static IList<IElement> HtmlToElements(string content)
ConverterProperties properties = new ConverterProperties();
properties.SetBaseUri(baseUri);
FontProvider fontProvider = new DefaultFontProvider(false, false, false);
FontProgram fontProgram = FontProgramFactory.CreateFont();
fontProvider.AddFont(fontProgram, "");
properties.SetFontProvider(fontProvider);
IList<IElement> elements = HtmlConverter.ConvertToElements(content, properties);
return elements;
【问题讨论】:
变量medImportantinfo
和tciImportantInfo
的类型为Cell
,但我在这些类中找不到ElementToCell()
方法。我不是 C# 开发人员,但我在 iText 7 for .NET 中也找不到该方法:github.com/itext/itext7-dotnet/blob/develop/itext/itext.layout/… 该方法是关于什么的?如果我用谷歌搜索,我只能找到对您问题的有效参考:google.com/search?q=iText+ElementToCell+cell
在Cell
上使用ElementToCell()
方法而不是Add()
方法很奇怪。当然,要使Add()
方法起作用,您可能需要将IElement
强制转换为IBlockElement
或Image
元素。
@BrunoLowagie 我刚刚添加了您所询问的函数的定义。我们自己定义了 ElementToCell 来处理不同的类型
好的,感谢您的澄清。我会在 Java 中使用 if (e instanceof IBlockElement)
之类的东西,但我不知道 C# 中是否存在。比较 string
的值对我来说看起来很尴尬,但由于我不懂 C#,所以我无法为您提供更多帮助..
@BrunoLowagie 没问题,感谢您的宝贵时间
【参考方案1】:
我通过阅读 iText 的文章解决了这个问题 https://developers.itextpdf.com/content/itext-7-converting-html-pdf-pdfhtml/chapter-6-using-fonts-pdfhtml
简单的改变
FontProvider fontProvider = new DefaultFontProvider(false, false, false);
到
FontProvider fontProvider = new DefaultFontProvider(true, true, true);
【讨论】:
以上是关于通过 iText 创建 PDF 文档时,某些 HTML 和 CSS 样式未应用的主要内容,如果未能解决你的问题,请参考以下文章