Java生成pdf工具——openPdf使用介绍

这里推荐使用openPdf,因为它遵循 LGPL and MPL开源协议,是基于 iText 4 svn tag。具体的可以参考github:https://github.com/LibrePDF/OpenPDF

1、增加相应的依赖
<dependency>
  <groupId>com.github.librepdf</groupId>
  <artifactId>openpdf</artifactId>
  <version>1.3.34</version>
</dependency>
<dependency>
  <groupId>com.github.librepdf</groupId>
  <artifactId>openpdf-fonts-extra</artifactId>
  <version>1.3.34</version>
</dependency>

这个版本是最后支持jdk1.8, 后续的版本需要jdk9+,使用时,根据jdk版本进行相应的选择。

2、基础API的介绍

1、针对中文的支持,必须创建支持中文字符的基础字体

BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font docFont = new Font(bfChinese, 10, Font.UNDEFINED, Color.BLACK);

2、Paragraph(段落) 、Phrase(短语)、Chunk(块),推荐使用Chunk 它是最小的文本块,也可以根据自己的需求做相应的选择。

3、Image(图片)

 byte[] byteArray = new byte[0];
            try (InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("logo.png")) {
                if (inputStream != null) {
                    byteArray = new byte[inputStream.available()];
                    inputStream.read(byteArray);
                }
            } catch (IOException e) {
                logger.warn("load logo.png failed", e);
            }
            Image image = Image.getInstance(byteArray);
            image.scaleAbsolute(73, 19); #对图片进行缩放

4、PdfPTable、PdfPCell

在使用它们的时候,需要注意,个人在使用过程经过压测发现,它们比较适合页面布局,不适合做数据迭代。在做数据列表展示时当数据里较大时,生成比较慢。在做数据展示时,下面会介绍。

            PdfPTable topTable = new PdfPTable(3);#创建三列的表
            topTable.setWidthPercentage(100f);#设置宽度百分比
            topTable.setSpacingAfter(20f);
            Paragraph paragraph = new Paragraph("寄件服务明细", titleFont);
            PdfPCell cell = new PdfPCell(paragraph); // 建立一个单元格
            cell.setColspan(2);#合并单元格
            cell.setBorder(0);
            cell.setHorizontalAlignment(Element.ALIGN_LEFT); // 设置内容水平居中显示
            topTable.addCell(cell);

5、Table、Cell

这两个相对于PdfPTable、PdfPCell 是较轻的API,也是比较适合做数据列表展示的(推荐使用)

            float[] widths = new float[]{5, 10, 15, 10, 10, 15, 10, 15, 10};
            String[] tableTitle = new String[]{"#", "业务类型", "运单号码", "订单时间", "寄方", "寄件地", "收方", "收件地", "金额(元)"};
            Table table = new Table(tableTitle.length);
            table.setWidths(widths);
            table.setWidth(100);
            table.setBorder(0);
            Chunk chunk;
            Cell cell1;
            for (int i = 0; i < tableTitle.length; i++) {
                chunk = new Chunk(tableTitle[i], headFont);
                cell1 = new Cell(chunk); // 建立一个单元格
                cell1.setHorizontalAlignment(HorizontalAlignment.CENTER); // 设置内容水平居中显示
                cell1.setVerticalAlignment(VerticalAlignment.CENTER); // 设置垂直居中
                cell1.setBackgroundColor(Color.DARK_GRAY);
                cell1.setBorderColor(Color.WHITE);
                table.addCell(cell1);
            }
3、生成pdf代码片段
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();// 输出到客户段的流
            Document document = new Document(); // 创建document对象
            PdfWriter.getInstance(document, byteArrayOutputStream);// 创建书写器
            document.open(); // 打开文档

            // 创建一个对中文字符集支持的基础字体
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font titleFont = new Font(bfChinese, 16, Font.BOLD);
            Font docFont = new Font(bfChinese, 10, Font.UNDEFINED, Color.BLACK);
            Font docFont2 = new Font(bfChinese, 10, Font.UNDEFINED, Color.GRAY);
            Font headFont = new Font(bfChinese, 12, Font.BOLD, Color.WHITE);

            PdfPTable topTable = new PdfPTable(3);
            topTable.setWidthPercentage(100f);
            topTable.setSpacingAfter(20f);
            Paragraph paragraph = new Paragraph("寄件服务明细", titleFont);
            PdfPCell cell = new PdfPCell(paragraph); // 建立一个单元格
            cell.setColspan(2);
            cell.setBorder(0);
            cell.setHorizontalAlignment(Element.ALIGN_LEFT); // 设置内容水平居中显示
            topTable.addCell(cell);

             document.add(topTable);

             document.close();// 关闭文档

4、下载pdf代码片段
try (ServletOutputStream outputStream = response.getOutputStream()) {
    ByteArrayOutputStream byteArrayOutputStream = businessDetailService.toPdf();
    // 输出到客户端
    response.setContentType("application/pdf; charset=utf-8");
    response.setHeader("Content-Disposition", "inline;filename=\"" + new Date().getTime() + ".pdf\"");
    byteArrayOutputStream.writeTo(outputStream);
    outputStream.flush();
} catch (Exception e) {
    logger.error("INVOICE_DOWNLOAD_PDF|FAIL", e;
    if (e instanceof ServiceException) {
        throw e;
    }
    throw new ServiceException(401, "下载PDF文件失败!");
}

以上个人在使用过程中的一些总结,希望对你有所帮助!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐