使用iText动态生成pdf,并用pdf.js在线预览

Java有很多生成pdf的工具库,常用的有Apache PdfBox,iText,POI。我的项目里用的是iText。
下面说下详细步骤:
后台引入依赖:

		<!--pdf生成类库-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
        <!--pdf支持亚洲字体-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

Java代码:

	/**标题字体*/
    private static Font titleFont = new Font(PdfUtils.chineseFont, 35, Font.BOLD, PdfUtils.baseColor);
    /**单元格字体*/
    private static Font cellFont = new Font(PdfUtils.chineseFont, 10, Font.NORMAL, PdfUtils.baseColor);

    @GetMapping("/getPdf")
    public void getPdf(String teacherName, HttpServletResponse response) {
        // 创建Pdf文档对象
        Document doc = new Document(PageSize.A4);
        PdfWriter pdfWriter = null;
        try {
            //指定pdf导出位置,这里我们直接将它导出给response的输出流,如果要导出到磁盘上的话就用FileOutputStream
            pdfWriter = PdfWriter.getInstance(doc, response.getOutputStream());
            doc.open();
            //*******添加第一页内容**********
            Paragraph title = PdfUtils.createCenterParagraph("三年1班学生表", titleFont);
            //设置文本块下间距
            title.setSpacingAfter(80);
            //将文本块加入pdf文档中
            doc.add(title);
            Paragraph teacher = PdfUtils.createRightParagraph("老师:" + teacherName, cellFont);
            doc.add(teacher);
            //******添加第二页内容***********
            //将纸张由竖向改为横向
            Rectangle rectangle = new Rectangle(PageSize.A4);
            doc.setPageSize(rectangle.rotate());
            doc.newPage();
            //创建一个有4列的表
            PdfPTable table = PdfUtils.createCenterTable(4);
            ArrayList<PdfPRow> tableRows = table.getRows();
            //表头
            PdfPCell[] headerCells = new PdfPCell[4];
            headerCells[0] = PdfUtils.createCell("姓名", cellFont);
            headerCells[1] = PdfUtils.createCell("学号", cellFont);
            headerCells[2] = PdfUtils.createCell("住址", cellFont);
            headerCells[3] = PdfUtils.createCell("性别", cellFont);
            PdfPRow headerRow = new PdfPRow(headerCells);
            tableRows.add(headerRow);

            for (int i = 0; i < 5; i++) {
                PdfPCell[] cells = new PdfPCell[4];
                cells[0] = PdfUtils.createCell("学生"+i, cellFont);
                cells[1] = PdfUtils.createCell(""+i, cellFont);
                cells[2] = PdfUtils.createCell("住址"+i, cellFont);
                cells[3] = PdfUtils.createCell(i%2 == 1? "男":"女", cellFont);
                PdfPRow row = new PdfPRow(cells);
                tableRows.add(row);
            }
            doc.add(table);
            doc.close();
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            if (doc != null) {
                doc.close();
            }
            if (pdfWriter != null) {
                pdfWriter.close();
            }
        }
    }

Pdf工具类:

/**
 * pdf工具类
 */
@Slf4j
public class PdfUtils {
    public static BaseFont chineseFont;
    public static BaseColor baseColor;
    static {
        try {
            //设置宋体
            chineseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            baseColor = BaseColor.BLACK;
        } catch (DocumentException | IOException e) {
            log.error("设置pdf初始字体异常", e);
        }
    }
    /**
     * 创建一个水平居中的文字段落
     * @param content 内容
     * @param font 字体
     * @return
     */
    public static Paragraph createCenterParagraph(String content, Font font) {
        Paragraph result = new Paragraph(content, font);
        result.setAlignment(Paragraph.ALIGN_CENTER);
        return result;
    }

    /**
     * 创建一个向右对齐的文字段落
     * @param content 内容
     * @param font 字体
     * @return
     */
    public static Paragraph createRightParagraph(String content, Font font) {
        Paragraph result = new Paragraph(content, font);
        result.setAlignment(Paragraph.ALIGN_RIGHT);
        return result;
    }

    /**
     * 创建一个文字段落,对齐方式自定义
     * @param content 内容
     * @param font 字体
     * @param alignment 对齐方式
     * @return
     */
    public static Paragraph createParagraph(String content, Font font, int alignment) {
        Paragraph result = new Paragraph(content, font);
        result.setAlignment(alignment);
        return result;
    }

    /**
     * 创建一个水平居中的表
     * @param numColumns 表的列数
     * @return
     */
    public static PdfPTable createCenterTable(int numColumns) {
        PdfPTable result = new PdfPTable(numColumns);
        result.setHorizontalAlignment(PdfPTable.ALIGN_CENTER);
        return result;
    }

    /**
     * 创建一个单元格,单元格内容水平居中垂直居中
     * @param content 单元格内容
     * @param font 字体
     * @return
     */
    public static PdfPCell createCell(String content, Font font) {
        PdfPCell result = new PdfPCell(new Phrase(content, font));
        //设置单元格内容垂直居中
        result.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
        //设置党员个内容水平居中
        result.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
        return result;
    }
}

下载pdf.js,下载地址https://github.com/mozilla/pdf.js/archive/gh-pages.zip
将压缩包中的web和build两个文件夹放到项目中
在这里插入图片描述
创建一个index.html页面进行测试,注意路径问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>pdf在线预览</title>
</head>
<body>
<input type="button" onclick="openPDF()" value="点我打开pdf预览"/>
<script>
    function openPDF(){
        var url="/getPdf";
        //引入的pdf.js文件夹的路径下的web/viewer.html 参数:后台流文件URL+teacherName=?
        //注意路径问题 %3D是“=”号的转义,
        window.open("./pdfjs/web/viewer.html?file="+ url + "?teacherName%3D陈大大");
    }

</script>
</body>
</html>

程序启动后浏览器访问127.0.0.1:8080/index.html,测试结果如下
在这里插入图片描述
在这里插入图片描述
这篇博客的代码在github上:https://github.com/chenzhixiang111/pdf-preview

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值