• 01.在Java中如何创建PDF文件


    1.简介

    在这篇快速文章中,我们将重点介绍基于流行的iText和PdfBox库从头开始创建 PDF 文档。

    2. Maven 依赖

    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.10</version>
    </dependency>
    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox</artifactId>
        <version>2.0.4</version>
    </dependency>
    

    可以在这里找到该库的最新版本:iTextPdfBox

    如果需要加密我们的文件,则需要添加一个额外的依赖项。The Bounty Castle Provider。软件包包含加密算法的实现,并且两个库都需要:

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.56</version>
    </dependency>
    

    可以在这里找到该库的最新版本:The Bounty Castle Provider

    3.概述

    iText 和 PdfBox 都是用于创建/操作 pdf 文件的 Java 库。尽管这些库的最终输出是相同的,但它们的操作方式略有不同。让我们看看它们。

    4.在 IText 中创建 Pdf

    4.1 在 Pdf 中插入文字

    让我们看一下将带有“ Hello World”文本的新文件插入 pdf 文件的方式

    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream("iTextHelloWorld.pdf"));
    
    document.open();
    Font font = FontFactory.getFont(FontFactory.COURIER, 16, BaseColor.BLACK);
    Chunk chunk = new Chunk("Hello World", font);
    
    document.add(chunk);
    document.close();
    

    使用 iText 库创建 pdf 的基础是操纵在 Document 中实现 Elements 接口的对象(在 5.5.10 版中,其中 45 种实现)。

    可以添加到文档中并使用的最小元素称为 Chunk,基本上是一个带有应用字体的字符串。

    此外,Chunk 可以与其他元素(如 Paragraphs,Section 等)结合使用,从而形成美观的文档。

    4.2 插入图片

    iText 库提供了一种将图像添加到文档的简便方法。我们只需要创建一个 Image 实例并将其添加到 Document 中。

    Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI());
    
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream("iTextImageExample.pdf"));
    document.open();
    Image img = Image.getInstance(path.toAbsolutePath().toString());
    document.add(img);
    
    document.close();
    

    4.3 插入表

    当我们想在 pdf 文件中添加表格时,可能会遇到问题。幸运的是,iText 提供了开箱即用的此类功能。

    首先,我们需要创建一个 PdfTable 对象,并在构造函数中为我们的表提供许多列。现在我们可以简单地通过调用添加新单元格

    现在,我们可以通过在新创建的表对象上调用 addCell 方法来简单地添加新单元格。只要定义了所有必需的单元格,iText 就会创建表行,这意味着一旦创建了一个包含 3 列的表并向其中添加 8 个单元格,则仅显示 2 行,每个行中包含 3 个单元格。

    让我们看一个例子:

    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream("iTextTable.pdf"));
    
    document.open();
    
    PdfPTable table = new PdfPTable(3);
    addTableHeader(table);
    addRows(table);
    addCustomRows(table);
    
    document.add(table);
    document.close();
    

    我们创建一个具有 3 列 3 行的新表。我们将第一行视为表格标题,其背景颜色和边框宽度已更改:

    private void addTableHeader(PdfPTable table) {
        Stream.of("column header 1", "column header 2", "column header 3")
          .forEach(columnTitle -> {
            PdfPCell header = new PdfPCell();
            header.setBackgroundColor(BaseColor.LIGHT_GRAY);
            header.setBorderWidth(2);
            header.setPhrase(new Phrase(columnTitle));
            table.addCell(header);
        });
    }
    

    第二行将由三个单元格组成,仅带有文本,没有额外的格式。

    private void addRows(PdfPTable table) {
        table.addCell("row 1, col 1");
        table.addCell("row 1, col 2");
        table.addCell("row 1, col 3");
    }
    

    我们不仅可以在单元格中包括文本,还可以包括图像。此外,每个单元格可能会分别设置格式,在下面提供的示例中,我们应用了水平和垂直对齐方式调整:

    private void addCustomRows(PdfPTable table)
      throws URISyntaxException, BadElementException, IOException {
        Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI());
        Image img = Image.getInstance(path.toAbsolutePath().toString());
        img.scalePercent(10);
    
        PdfPCell imageCell = new PdfPCell(img);
        table.addCell(imageCell);
    
        PdfPCell horizontalAlignCell = new PdfPCell(new Phrase("row 2, col 2"));
        horizontalAlignCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(horizontalAlignCell);
    
        PdfPCell verticalAlignCell = new PdfPCell(new Phrase("row 2, col 3"));
        verticalAlignCell.setVerticalAlignment(Element.ALIGN_BOTTOM);
        table.addCell(verticalAlignCell);
    }
    

    4.4 文件加密

    为了使用 iText 库应用权限,我们需要已经创建了 pdf 文档。在我们的示例中,我们将使用之前生成的 iTextHelloWorld.pdf 文件。

    使用 PdfReader 加载文件后,我们需要创建一个 PdfStamper,用于将其他内容应用于元数据,加密等文件:

    PdfReader pdfReader = new PdfReader("HelloWorld.pdf");
    PdfStamper pdfStamper
      = new PdfStamper(pdfReader, new FileOutputStream("encryptedPdf.pdf"));
    
    pdfStamper.setEncryption(
      "userpass".getBytes(),
      ".getBytes(),
      0,
      PdfWriter.ENCRYPTION_AES_256
    );
    
    pdfStamper.close();
    

    在我们的示例中,我们使用两个密码对文件进行了加密。用户密码(“ userpass”)(其中用户仅具有只读权限而无法打印),以及所有者密码(“ ownerpass”)用作主密钥,允许用户完全访问 pdf。

    如果我们希望允许用户打印 pdf,而不是 0(setEncryption 的第三个参数),我们可以传递:

    PdfWriter.ALLOW_PRINTING
    

    当然,我们可以混合使用不同的权限,例如:

    PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY
    

    请记住,使用 iText 设置访问权限,我们还将创建一个临时 pdf,应将其删除;否则,任何人都可以完全访问它。

    5.在 PdfBox 中创建 Pdf

    5.1 在 Pdf 中插入文字

    与 iText 相反,PdfBox 库提供了基于流操作的 API。没有类似 Chunk / Paragraph 等的类。PDDocument 类是内存中的 Pdf 表示形式,用户可以通过操纵 PDPageContentStream 类来写入数据。

    让我们看一下代码示例:

    PDDocument document = new PDDocument();
    PDPage page = new PDPage();
    document.addPage(page);
    
    PDPageContentStream contentStream = new PDPageContentStream(document, page);
    
    contentStream.setFont(PDType1Font.COURIER, 12);
    contentStream.beginText();
    contentStream.showText("Hello World");
    contentStream.endText();
    contentStream.close();
    
    document.save("pdfBoxHelloWorld.pdf");
    document.close();
    

    5.2 插入图片

    插入图像非常简单。

    首先,我们需要加载一个文件并创建一个 PDImageXObject,然后将其绘制在文档上(需要提供确切的 x,y 坐标)。

    就这样:

    PDDocument document = new PDDocument();
    PDPage page = new PDPage();
    document.addPage(page);
    
    Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI());
    PDPageContentStream contentStream = new PDPageContentStream(document, page);
    PDImageXObject image
      = PDImageXObject.createFromFile(path.toAbsolutePath().toString(), document);
    contentStream.drawImage(image, 0, 0);
    contentStream.close();
    
    document.save("pdfBoxImage.pdf");
    document.close();
    

    5.3 插入表格

    不幸的是,PdfBox 不提供任何允许创建表的现成方法。在这种情况下,我们可以手动绘制–从字面上看,画出每条线,直到我们的绘图类似于我们梦想中的桌子为止。

    5.4 文件加密

    PdfBox 库为用户提供了加密和调整文件权限的可能性。与 iText 相比,它不需要使用已经存在的文件,因为我们只使用 PDDocument。Pdf 文件权限由 AccessPermission 类处理,我们可以在其中设置用户是否可以修改,提取内容或打印文件。

    随后,我们创建一个 StandardProtectionPolicy 对象,该对象将基于密码的保护添加到文档中。我们可以指定两种类型的密码。用户密码,之后用户将可以使用已应用的访问权限和所有者密码打开文件(对该文件无限制):

    PDDocument document = new PDDocument();
    PDPage page = new PDPage();
    document.addPage(page);
    
    AccessPermission accessPermission = new AccessPermission();
    accessPermission.setCanPrint(false);
    accessPermission.setCanModify(false);
    
    StandardProtectionPolicy standardProtectionPolicy
      = new StandardProtectionPolicy("ownerpass", "userpass", accessPermission);
    document.protect(standardProtectionPolicy);
    document.save("pdfBoxEncryption.pdf");
    document.close();
    

    我们的示例提出了一种情况,如果用户提供用户密码,则无法修改和打印文件。

    6.结论

    在本教程中,我们讨论了在两个流行的 Java 库中创建 pdf 文件的方法。

  • 相关阅读:
    CSS Grid 布局
    sublime text 3配置c/c++编译环境
    [工具/PC]计算机中丢失libiconv-2.dll,丢失libintl-8.dll,无法定位程序输入点libiconv于动态链接库libiconv-2.dll上问题解决方法
    操作系统Unix、Windows、Mac OS、Linux的故事
    编译型语言与解释型语言的区别及各自的优缺点
    node版本控制之nvm
    Webpack devServer中的 proxy 实现跨域
    webpack-dev-server配置指南(使用webpack3.0)
    [bzoj3295][Cqoi2011]动态逆序对_主席树
    [bzoj2989]数列_KD-Tree_旋转坐标系
  • 原文地址:https://www.cnblogs.com/yu-yi/p/11647792.html
Copyright © 2020-2023  润新知