【问题标题】:Programmatic Application of CSS Stylings in iText7 (not html2pdf)iText7 中 CSS 样式的编程应用(不是 html2pdf)
【发布时间】:2023-04-08 15:08:01
【问题描述】:

我正在努力从 iText5 升级到 iText7。我想利用使用 CSS 定义和应用样式的能力——但我没有进行 html2pdf 转换。我们目前正在以编程方式构建我们的报告。有没有一种很好的方法可以让我们为 Document 设置 CSS 并在构建 Document 时应用样式?谢谢!

【问题讨论】:

    标签: css itext styles themes itext7


    【解决方案1】:

    我假设您正在构建基于 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;
        }
    }
    

    结果:

    【讨论】:

      猜你喜欢
      • 2018-05-24
      • 2019-12-26
      • 2017-12-27
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 2020-04-29
      • 1970-01-01
      • 2020-08-23
      相关资源
      最近更新 更多