在结构化的 iText(Sharp) 文档(章和节)中绘制图形对象(框和线)

Drawing graphical objects (boxes and lines) inside a structured iText(Sharp) document (Chapters and Sections)

我正在使用 iTextSharp 创建一个 PDF 文档,我正在做的是在 c# List<Chapter> 中生成我的所有内容,其中章节包含一个或多个部分,并且这些章节尚未完成添加到文档中。然后我通过我的 List<Chapter> 枚举在文档的开头生成 table 的内容,然后在我的 TOC 之后将章节添加到文档中。

当我的部分包含文本和图像时效果很好,但现在我需要生成一个包含框和线条的部分。我不想将我的方框和线条绘制到图像中并将图像拖放到“部分”中,这看起来不如我有实际的 PDF 方框和线条。

包含图形元素的部分可以与包含文本的部分混合使用,因此我需要一种方法来向部分添加某种元素,以便该图形部分仅在进入新页面时像文本部分一样工作如有必要。

最好的方法是什么?我觉得它以某种方式涉及 PdfTemplates 但我不确定如何。或者我可能需要创建一个 PdfPTable 并在 IPdfPCellEvent 中创建我的图形元素?

当您想要涉及 PdfTemplate 个元素时,您就走在了正确的轨道上。 PdfTemplate 是一个 iText 对象,对应于 PDF 规范中 Form XObjects 的概念。我们选择了另一个名称,因为 Form 这个词有些误导(人们将它与表单字段、交互式表单等混淆)。

PDF 页面的内容流是一系列 PDF 语法,由操作数和运算符组成。 XObject 是此内容流外部的对象。 XObject 的内容仅在 PDF 文档中存储一次,但可以在同一页面、不同页面上多次重复使用。

有不同类型的 XObjects,但 Image XObjectsForm XObjects 是最重要的。

  • Image XObjects 在我们处理光栅图像时使用。你写的绝对正确:*"I don't want to draw my boxes and lines into an image and drop the image into the Section, that won't look as good as if I have actual PDF boxes and lines."
  • 当我们想要重用 PDF 语法时,可以使用 Form XObjects。这就是您所需要的:您想要定义 moveTo()lineTo()curveTo()stroke()fill()、...操作,并且您需要这些行和形状存储为矢量数据。

您的问题的解决方案是在 PdfTemplate 对象上绘制线条和形状,然后将 PdfTemplate 对象包裹在 Image 对象中。当您将 Image 对象添加到 SectionChapter 时,它将作为 Form XObject 添加。您不必担心它会退化为光栅图像。

您可以在官方网站上找到此技术的一些示例。例如在问题的答案中 How to generate 2D barcode as vector image?

这里我们创建一个带有条形码的 PdfTemplate 并且我们 return 它作为一个 Image 对象。显示生成的 PDF 内部结构的屏幕截图证明条形码是作为矢量图像添加的。

public Image createBarcode(PdfContentByte cb, String text,
    float mh, float mw) throws BadElementException {
    BarcodePDF417 pf = new BarcodePDF417();
    pf.setText("BarcodePDF417 barcode");
    Rectangle size = pf.getBarcodeSize();
    PdfTemplate template = cb.createTemplate(
        mw * size.getWidth(), mh * size.getHeight());
    pf.placeBarcode(template, BaseColor.BLACK, mh, mw);
    return Image.getInstance(template);
}

要创建一个 PdfTemplate 对象,您需要一个 PdfContentByte 实例(例如使用 writer.getDirectContent())并使用 createTemplate() 方法传递宽度和高度作为参数.然后将内容绘制到 PdfTemplate 并使用 Image.getInstance().

将其转换为 Image 对象

您可以在我的书的 Absolute positioning of lines and shapes and in the example section of Chapter 3 and Chapter 14 章节中找到有关绘制线条和形状的更多信息。