【问题标题】:How to manage the overflow data in itext 7 when using canvasrenderer使用canvasrenderer时如何管理itext 7中的溢出数据
【发布时间】:2020-03-05 01:02:51
【问题描述】:

我正在使用 iText 7 从保存在数据库中的 html 文件生成 pdf 文件。

我使用以下代码生成 pdf,但 html 文件中的一半表格被忽略。我猜包含表格的IBlockElement 的大小大于画布的大小。

有什么办法解决这个问题吗?

List<IElement> elements = (List<IElement>)HtmlConverter.ConvertToElements(html);   
for (int k = 0; k < elements.Count; k++)
    {

        if (!renderer.IsFull())
        {
            canvas.Add((IBlockElement)elements[k]);
        }
        else
        {
            page = pdfDoc.AddNewPage();
            pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(),pdfDoc);
            rectangle = new Rectangle(offset, offset, pageWidth, pageHeight);
            pdfCanvas.Rectangle(rectangle);
            pdfCanvas.Stroke();
            canvas = new iText.Layout.Canvas(pdfCanvas, pdfDoc, rectangle);
            renderer = new MyCanvasRenderer(canvas);
            canvas.SetRenderer(renderer);
        }
    }

MyCanvasRenderer的实现:

class MyCanvasRenderer : CanvasRenderer {
    protected bool full = false;

    public MyCanvasRenderer(Canvas canvas) : base(canvas) {
    }

    public override void AddChild(IRenderer renderer) {
        base.AddChild(renderer);
        full = true.Equals(GetPropertyAsBoolean(Property.FULL));
    }

    public bool IsFull() {
        return full;
    }
}

【问题讨论】:

    标签: c#-4.0 itext7


    【解决方案1】:

    Canvas 类主要针对需要将元素添加到页面/XObject 上的特定预定义区域的情况,它的目的不是将您的内容溢出到下一个区域。

    由于所描述的用例只是将HTML 转换为PDF,因此要使用的适当API 是HtmlConverter 的另一种方法,它允许您在一行中将HTML 转换为PDF

    HtmlConverter.ConvertToPdf(html, pdfWriter);
    

    UPD:澄清@Saeed 的附加要求

    首页的边距不同

    CSS 允许您使用@page 媒体指定页边距,这些声明由pdfHTML 拾取。以下是页边距规范的示例以及如何为第一页自定义它们:

    @page {
        margin-top: 100pt;
        margin-left: 36pt;
        margin-right: 36pt;
        margin-bottom: 36pt;
    }
    
    @page:first {
        margin-top: 100pt;
        margin-left: 36pt;
        margin-right: 36pt;
        margin-bottom: 36pt;
    }
    

    避免将表格拆分为多个页面

    CSS 具有page-break-inside 属性,用于控制元素的页面外观。特别是,您对防止跨页面拆分元素的 page-break-inside: avoid; 声明感兴趣。

    您可以将此声明应用于文档中的所有表格:

    table {
        page-break-inside: avoid;
    }
    

    或者,您可以创建自己的类并仅在必要时应用它:

    .avoid-page-breaks {
        page-break-inside: avoid;
    }
    
    <table class="avoid-page-breaks">
    ...
    </table>
    

    第三个选项是将此样式应用于内联表格:

    <table style="page-break-inside: avoid;">
    ...
    </table>
    

    【讨论】:

    • 先解释一下我要生成的pdf文件的规格:首先不同的页面需要有不同的页边距,这是因为第一页的header logo很大,还有需要检查 html 表格的单元格是否在一页中(不拆分到不同的页面)。您认为 HtmlConverter 是否可以应用这些功能?
    • @Saeed 我已经编辑了我的答案。长话短说,CSS 允许这些东西开箱即用,所以你应该使用 CSS。只需编辑您的 HTML/CSS 文件,pdfHTML 就会选择这些配置。
    • 感谢 Alexey 的帮助,使用 css 即可。虽然我仍然很想知道如何将段落或文本添加到 Itext Renderer 而不会丢失任何数据而文本的长度大于 Renderer 的大小
    • 还有一个关于使用HtmlConverter.ConvertToPdf的问题,我可以用这个命令生成页眉和页脚吗?我需要在生成的 pdf 中添加页眉和页脚
    • @Saeed 添加内容时需要的空间比您拥有的空间多,您可以在渲染器级别工作。您可以通过调用Element.createRendererSubtree 开始并探索结果具有哪些 API。但由于 HTML 可能非常复杂,它并不总是与简单元素 1:1 对应,因此建议直接使用 HtmlConverter
    猜你喜欢
    • 2018-09-11
    • 2016-03-30
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2020-10-14
    • 2016-12-06
    • 1970-01-01
    • 2018-11-16
    相关资源
    最近更新 更多