Java-模板生成PDF方式2-PDFBox

发布时间 2023-06-06 15:08:44作者: 西可

PDFBox文本域+内容流生成PDF

BSD许可下的源码开放项目

pom.xml引入依赖

    <!-- pdfbox生成PDF -->
    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox</artifactId>
        <version>2.0.27</version>
    </dependency>

生成PDF的util类

    final static String FONT_SEGUISYM = "fonts/seguisym.ttf";
    final static String FONT_SIMHEI = "fonts/simhei.ttf";
    final static String TEMPLATE = "templates/applying_for_volunteer_service_form_pdfBox.pdf";

    public static void generatePdf(OutputStream os, Message message, List<String> pickVolunteers, Map<String, List<DictData>> allVolunteers, List<DictData> volunteerTypes) throws IOException, DocumentException {
        InputStream templateInputStream = new ClassPathResource(template).getInputStream();
        try (PDDocument pdfDocument = PDDocument.load(templateInputStream)) {

            // 1:使用文本域填充模板 -- 基础数据
            buildBasicData(pdfDocument,message);

            // 2:使用内容流写入数据 -- 特殊数据
            // 配置类型
            buildVolunteerTypes(pdfDocument,message.getVolunteerType(),volunteerTypes);
            // 配置志愿服务
            buildAllVolunteers(pdfDocument,allVolunteers,pickVolunteers);
            // 特殊复选框
            buildCheckBox(pdfDocument);

            // 3:保存文档
            pdfDocument.save(os);
        }
    }

资源

使用到的字体

fonts/seguisym.ttf
fonts/simhei.ttf

使用到的模板

template/applying_for_volunteer_service_form_pdfBox.pdf

源码地址

https://gitee.com/cocoxike/pdfdemo.git

效果图

image

遇到的问题

1.PDF自带的14种字体无法输出中文->使用嵌入字体,会导致生成的pdf文件偏大——>载入字体子集化

image

InputStream simfangInputStream = new ClassPathResource("fonts/simhei.ttf").getInputStream();

PDFont simfangFont = PDType0Font.load(pdfDocument, simfangInputStream, false);       
// 改为 -- 默认字体在嵌入前子集化(嵌入所有未使用到的字体会使pdf文档变的很大,所以将其子集化)
PDFont simfangFont = PDType0Font.load(pdfDocument, simfangInputStream);   

2.PDF写入复选框,同样需要嵌入特殊字体。

/**
 * 复选框选中
 */
public final static String CHECK_BOX = "☑";
/**
 * 复选框未选中
 */
public final static String UN_CHECK_BOX = "☐";

PDType0Font.load(doc, new File("C:\\Windows\\Fonts\\seguisym.ttf"))

3.嵌入字体显示外观比较细,无法调整为粗体。-->未解决--> 通过更换字体处理

4.多行行距无法调整。-->未解决--->通过内容流处理(绝对位置)

5.文本域+内容流 写入内容显示,pdf原有文本不显示

/** 内容流默认覆盖原有内容
APPEND 附加--将内容流附加到所有现有页面内容流之后。
OVERWRITE 覆盖--覆盖现有页面内容流。
PREPEND 预置--在所有其他页面内容流之前插入。
*/
PDPageContentStream contentStream = new PDPageContentStream(pdfDocument, page);
// 创建内容流 增加预置参数
PDPageContentStream contentStream = new PDPageContentStream(pdfDocument, page,PDPageContentStream.AppendMode.PREPEND, false);