Java实现格式转换为PDF的两种方案

在Java中实现格式转换为PDF,通常需要借助第三方开源库。目前业界最常用且功能强大的两个库是 iText 和 Apache PDFBox

以下我将为您提供基于这两种主流方案的完整逻辑与代码示例,涵盖最常见的三种转换场景:纯文本转PDF图片转PDF 以及 HTML网页转PDF

方案一:使用 iText 库(推荐,API更高级)

iText 提供了丰富的文档排版能力,非常适合生成复杂的报表或文档。

1. 引入 Maven 依赖1. 引入 Maven 依赖

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.5</version>
    <type>pom</type>
</dependency>
<!-- 如果需要HTML转PDF,还需要引入 pdfHTML -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>html2pdf</artifactId>
    <version>4.0.3</version>
</dependency>

2. 完整转换工具类代码

import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.io.image.ImageDataFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class PdfConverter {

    /**
     * 1. 纯文本 (TXT) 转换为 PDF
     */
    public static void textToPdf(String txtPath, String pdfPath) throws IOException {
        // 读取文本内容
        String content = new String(Files.readAllBytes(Paths.get(txtPath)), StandardCharsets.UTF_8);
        
        try (PdfWriter writer = new PdfWriter(pdfPath);
             PdfDocument pdfDoc = new PdfDocument(writer);
             Document document = new Document(pdfDoc, PageSize.A4)) {
            
            // 将文本按行分割并添加到PDF中
            for (String line : content.split("\n")) {
                document.add(new Paragraph(line));
            }
        }
    }

    /**
     * 2. 图片转换为 PDF
     */
    public static void imageToPdf(String imagePath, String pdfPath) throws Exception {
        try (PdfWriter writer = new PdfWriter(pdfPath);
             PdfDocument pdfDoc = new PdfDocument(writer);
             Document document = new Document(pdfDoc, PageSize.A4)) {
            
            Image image = new Image(ImageDataFactory.create(imagePath));
            // 缩放图片以适应A4纸张宽度
            image.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight()); 
            document.add(image);
        }
    }

    /**
     * 3. HTML 字符串/文件转换为 PDF
     */
    public static void htmlToPdf(String htmlContent, String pdfPath) throws IOException {
        try (OutputStream os = new FileOutputStream(pdfPath)) {
            // 核心方法:直接将HTML流转换为PDF流
            HtmlConverter.convertToPdf(htmlContent, os);
        }
    }

    // 测试入口
    public static void main(String[] args) throws Exception {
        // 示例:HTML转PDF
        String html = "<h1>Hello PDF</h1><p>这是一段由Java生成的PDF内容。</p>";
        htmlToPdf(html, "output_from_html.pdf");
    }
}

方案二:使用 Apache PDFBox 库(轻量级,完全免费开源)

PDFBox 在处理基础的文本写入和图片嵌入时非常稳定,适合不需要复杂排版的场景。

1. 引入 Maven 依赖

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.24</version>
</dependency>

2. 基础文本写入示例

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import java.io.IOException;

public class PdfBoxConverter {
    public static void createSimplePdf(String pdfPath, String text) throws IOException {
        try (PDDocument document = new PDDocument()) {
            PDPage page = new PDPage();
            document.addPage(page);

            try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
                contentStream.beginText();
                contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
                contentStream.newLineAtOffset(100, 700); // 设置文本起始坐标
                contentStream.showText(text);
                contentStream.endText();
            }
            document.save(pdfPath);
        }
    }
}

核心开发建议与注意事项:

  1. 中文乱码问题:上述 iText 和 PDFBox 的基础示例使用的是默认英文字体。如果您的业务涉及中文转换,必须在代码中显式加载中文字体文件(如 msyh.ttf 微软雅黑),否则生成的PDF会出现乱码或方块。
  2. 资源释放:无论使用哪种库,务必确保 DocumentPdfWriter 或 ContentStream 等对象在使用后被正确关闭(推荐使用 Java 的 try-with-resources 语法),以防止内存泄漏和文件被占用无法删除。
  3. HTML转PDF的局限性:在使用 iText 的 html2pdf 模块时,它不支持所有的 CSS3 特性(如部分伪类 :hover 或 @import 规则)。对于复杂的网页,建议在转换前先将外部CSS内联化。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注