【发布时间】:2023-04-08 15:08:01
【问题描述】:
我正在努力从 iText5 升级到 iText7。我想利用使用 CSS 定义和应用样式的能力——但我没有进行 html2pdf 转换。我们目前正在以编程方式构建我们的报告。有没有一种很好的方法可以让我们为 Document 设置 CSS 并在构建 Document 时应用样式?谢谢!
【问题讨论】:
标签: css itext styles themes itext7
我正在努力从 iText5 升级到 iText7。我想利用使用 CSS 定义和应用样式的能力——但我没有进行 html2pdf 转换。我们目前正在以编程方式构建我们的报告。有没有一种很好的方法可以让我们为 Document 设置 CSS 并在构建 Document 时应用样式?谢谢!
【问题讨论】:
标签: css itext styles themes itext7
我假设您正在构建基于 layout 模块中的元素的元素结构,因为您没有使用 pdfHTML。 CSS 样式与您可以设置为 layout 模块中元素的样式之间没有 1-1 对应关系 - 某些 CSS 样式会影响元素的结果结构和元素的内容(例如大小写更改等),以及 pdfHTML插件会处理所有这些。
这意味着将现有 CSS 样式应用到 layout 模块的元素结构的可能性非常有限。最好的方法是编写 HTML+CSS 标记并使用HtmlConverter#convertToElements 转换为layout 元素结构。您将不得不编写一些代码来充当 CSS 和布局之间的桥梁。示例:
Document document = new Document(new PdfDocument(new PdfWriter("C:/out.pdf")));
Paragraph p = new Paragraph("Hello world");
Map<String, String> cssStyles = new HashMap<>();
// Font size is the required field
cssStyles.put("font-size", "12pt");
cssStyles.put("color", "red");
// No shorthand properties are allowed
cssStyles.put("border-left-color", "black");
cssStyles.put("border-left-style", "solid");
cssStyles.put("border-left-width", "1px");
DummyStylesContainer container = new DummyStylesContainer();
container.setStyles(cssStyles);
ProcessorContext context = new ProcessorContext(new ConverterProperties());
context.getCssContext().setRootFontSize(12);
BlockCssApplier applier = new BlockCssApplier();
applier.apply(context, container, new DummyTagWorker(p));
document.add(p);
document.close();
助手类定义:
private static class DummyStylesContainer implements IStylesContainer {
private Map<String, String> map;
@Override
public void setStyles(Map<String, String> stringStringMap) {
this.map = stringStringMap;
}
@Override
public Map<String, String> getStyles() {
return map;
}
}
private static class DummyTagWorker implements ITagWorker {
private IPropertyContainer container;
public DummyTagWorker(IPropertyContainer container) {
this.container = container;
}
@Override
public void processEnd(IElementNode element, ProcessorContext context) {
}
@Override
public boolean processContent(String content, ProcessorContext context) {
return false;
}
@Override
public boolean processTagChild(ITagWorker childTagWorker, ProcessorContext context) {
return false;
}
@Override
public IPropertyContainer getElementResult() {
return container;
}
}
【讨论】: