如何使用JAVA生成自定义格式的pdf文件(IText)

     最近接手一个生成PDF授权书的需求,公司使用JDK8,于是还是先搜了搜使用JAVA语言如何操作授权书,经过筛选最终选择了IText,因为api比较通俗,并且社区还算活跃,下面则是对一些常用到的方法做了个总结(使用的是itext5的api)

Itext官方网址:https://itextpdf.com/en

准备工作:加依赖,我使用的是Itext5,推荐使用最新的itext7,新的功能更加丰富,有时间我会进行升级。


    com.itextpdf
    itext-asian
    5.2.0

首先,对于授权书的生成有三个想法:

1.填充文本方式

授权书嘛,想想就是pdf中大部分数据内容都是相同的,可能就是每个用户的授权主体,授权时间,电话什么的不同,所以思路就是预先生成好授权书的源文件,就是将对于用户相同的内容先写好到授权书,然后将对于每个用户不用的数据预留出空间来进行内容的填充。但是比较麻烦的是需要定位的填充内容的位置,通过x,y的坐标定位填写内容的起始位置。

如何使用JAVA生成自定义格式的pdf文件(IText)_第1张图片

如上图,对于授权方相关的信息每个用户都是一样的,所以可以提前生成一个内容都写好的pdf文件,然后将被授权方需要填写的内容空出来,根据每个用户填写的不同信息分别填充不同的内容。代码:

// 读取pdf源文件
        try(InputStream is = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\source_v1.pdf"))){
            // 设置字体样式 这种是使用自定义的字体,也可以使用默认的字体,但是默认字体格式太少,一般都是使用自定义的吧
            BaseFont font = BaseFont.createFont("C:\\Users\\Administrator\\Desktop\\simkai.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

            // 替换文本
            PdfReader reader = new PdfReader(is); // input PDF
            PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\res.pdf"))); // output PDF
            // 获取pdf文件第一页内容
            PdfContentByte pageOne = stamper.getOverContent(1);
            // 被授权方
            setText(pageOne,410,580,"王大套",font,10);
            //社会信用代码
            setText(pageOne,410,559,"130xxxxxxxxxxxxxx0223",font,10);
            // 电话
            setText(pageOne,410,538,"131xxxx1234",font,10);
            // 用户ID
            setText(pageOne,410,517,"uid123_adskjflEMDK-dagjKJETD",font,10);
            // 绘制
            pageOne.fill();
            // 关闭
            stamper.flush();
            stamper.close();
        }catch (Exception e){
            e.printStackTrace();
        }

结果:如何使用JAVA生成自定义格式的pdf文件(IText)_第2张图片

基本可以满足需求。

2.替换文本方式

这个也是个思路,但是没有使用,就是利用itext文本替换的功能,和方案1类似,将需要进行自定义填写的内容使用占位符,比如"被授权方:${the_auth_user}",然后用替换方式将字符串为"${the_auth_user}"替换成"王大套",也可以达到效果,这个大家可以试试,我也试过可以实现,但是没有使用。

3.从头生成

第三种就是如果每个用户的绝大部分内容都不相同呢,这样我们无法找个一个合适的文件作为源文件,所以干脆从头到尾生成一个pdf文件。

如何使用JAVA生成自定义格式的pdf文件(IText)_第3张图片

如上图,这是一般授权书的内容,有图片,有表格,有文字,示例代码:

String path = "C:\\Users\\Administrator\\Desktop\\";

        // 设置字体样式
         黑色字体
        BaseFont bfChinese = BaseFont.createFont(path + "simkai.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        Font blackFont = new Font(bfChinese);
        blackFont.setSize(12);
        blackFont.setStyle(FontFactory.HELVETICA);
        blackFont.setColor(BaseColor.BLACK);
         红色字体
        Font redFont = new Font(bfChinese);
        redFont.setSize(12);
        redFont.setStyle(FontFactory.HELVETICA);
        redFont.setColor(BaseColor.RED);
         橙色字体
        Font orangeFont = new Font(bfChinese);
        orangeFont.setSize(12);
        orangeFont.setStyle(FontFactory.HELVETICA);
        orangeFont.setColor(BaseColor.ORANGE);

        // 设置页面信息  A4纸,页边距
        Document doc = new Document(PageSize.A4,90.14f,90.14f,72f,72f);
        OutputStream out = new FileOutputStream(new File(path + "aaa.pdf"));

        PdfWriter.getInstance(doc, out);
        doc.open();
        // 授权书标题
        Paragraph title = new Paragraph("授权书(个人VIP)", blackFont);
        title.setAlignment(Element.ALIGN_CENTER);
        doc.add(title);
        doc.add(new Paragraph("\n"));

        // 设计信息表格
        // 设置 3 列表格
        PdfPTable table = new PdfPTable(3);
        // 设置表格宽度
        table.setTotalWidth(new float[]{20,40,40});// 这里是百分比,每列所占整个宽度的比例
        table.setTotalWidth(414.992f);// 这是设置表格的定宽
        table.setLockedWidth(true);// 这个必须设置为true,意思是按照我们设置的锁定表格的宽度
        table.setHorizontalAlignment(Element.ALIGN_CENTER);
        // 图片
        Image cellimg = Image.getInstance(path + "thumb.png");
        PdfPCell cell1 = new PdfPCell(cellimg, true);
        cell1.setBorderColor(BaseColor.GRAY);// 单元格边框颜色
        cell1.setPaddingLeft(10);
        cell1.setFixedHeight(100);
        cell1.setLeading(20,1);
        cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell1.setVerticalAlignment(Element.ALIGN_CENTER);
        cell1.setRowspan(4);
        cell1.setFixedHeight(50);
        cell1.setTop(10);
        table.addCell(cell1);
        // 授权方
        PdfPCell cell2 = new PdfPCell(new Paragraph("授权方:xxxxx",blackFont));
        cell2.setBorderColor(BaseColor.GRAY);
        cell2.setPaddingLeft(10);
        cell2.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell2.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell2);
        // 被授权方
        PdfPCell cell3 = new PdfPCell();
        Paragraph elements = new Paragraph();
        elements.add(new Chunk("被授权方:王大套", blackFont));
        cell3.setPhrase(elements);
        cell3.setBorderColor(BaseColor.GRAY);
        cell3.setPaddingLeft(10);
        cell3.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell3.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell3);
        // 授权方网站
        PdfPCell cell4 = new PdfPCell(new Paragraph("授权⽅⽹站:xxxxx",blackFont));
        cell4.setBorderColor(BaseColor.GRAY);
        cell4.setPaddingLeft(10);
        cell4.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell4.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell4);
        // 身份证/统⼀社会信⽤代码:
        PdfPCell cell5 = new PdfPCell(new Paragraph("身份证/统⼀社会信⽤代码:xxxxxx",blackFont));
        cell5.setBorderColor(BaseColor.GRAY);
        cell5.setPaddingLeft(10);
        cell5.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell5.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell5);
        // 地址
        PdfPCell cell6 = new PdfPCell(new Paragraph("地址:xxxxxx",blackFont));
        cell6.setBorderColor(BaseColor.GRAY);
        cell6.setPaddingLeft(10);
        cell6.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell6.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell6);
        // 地址
        PdfPCell cell7 = new PdfPCell(new Paragraph("地址:xxxxxxx",blackFont));
        cell7.setBorderColor(BaseColor.GRAY);
        cell7.setPaddingLeft(10);
        cell7.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell7.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell7);
        // 设计ID
        PdfPCell cell8 = new PdfPCell();
        Paragraph elements1 = new Paragraph();
        elements1.add(new Chunk("内容id:", redFont));
        elements1.add(new Chunk("sdfasd-DALKDA-dagfsadf", blackFont));
        cell8.addElement(elements1);
        cell8.setBorderColor(BaseColor.GRAY);
        cell8.setPaddingLeft(10);
        cell8.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell8.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell8);
        // 联系电话
        PdfPCell cell9 = new PdfPCell(new Paragraph("联系电话:xxxxxx",blackFont));
        cell9.setBorderColor(BaseColor.GRAY);
        cell9.setPaddingLeft(10);
        cell9.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell9.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell9);
        // 空白
        PdfPCell cell10 = new PdfPCell(new Paragraph(" ",blackFont));
        cell10.setBorderColor(BaseColor.GRAY);
        cell10.setPaddingLeft(10);
        cell10.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell10.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell10);
        // 空白
        PdfPCell cell11 = new PdfPCell(new Paragraph(" ",blackFont));
        cell11.setBorderColor(BaseColor.GRAY);
        cell11.setPaddingLeft(10);
        cell11.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell11.setVerticalAlignment(Element.ALIGN_MIDDLE);
        table.addCell(cell11);

        // 被授权⽤户ID:
        PdfPCell cell12 = new PdfPCell(new Paragraph("被授权⽤户ID:xxxxxx",blackFont));
        cell12.setBorderColor(BaseColor.GRAY);
        cell12.setPaddingLeft(10);
        cell12.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell12.setVerticalAlignment(Element.ALIGN_TOP);
        table.addCell(cell12);
        doc.add(table);
        doc.add(new Paragraph("\n"));

        // 授权内容
        Paragraph temp = new Paragraph("1.授权内容", blackFont);
        temp.setLeading(23);
        temp.setAlignment(Element.ALIGN_LEFT);
        doc.add(temp);
        temp = new Paragraph("xxxxxx", blackFont);
        temp.setLeading(23);
        temp.setAlignment(Element.ALIGN_LEFT);
        doc.add(temp);
        doc.add(new Paragraph("\n"));// 换行

        temp = new Paragraph("2.授权范围", blackFont);
        temp.setLeading(23);
        temp.setAlignment(Element.ALIGN_LEFT);
        doc.add(temp);
        temp = new Paragraph("xxxxxx", blackFont);
        temp.setLeading(23);
        temp.setAlignment(Element.ALIGN_LEFT);
        doc.add(temp);
        doc.add(new Paragraph("\n"));// 换行

        temp = new Paragraph("xxxxx公司", blackFont);
        temp.setLeading(23);
        temp.setAlignment(Element.ALIGN_RIGHT);
        doc.add(temp);
        temp = new Paragraph("2020 年 03 月 28 日", blackFont);
        temp.setLeading(23);
        temp.setAlignment(Element.ALIGN_RIGHT);
        doc.add(temp);
        doc.add(new Paragraph("\n"));// 换行

        doc.close();

结果:

如何使用JAVA生成自定义格式的pdf文件(IText)_第4张图片

也是基本达到要求,当然都是伪代码,基本注释都写了,真正生产环境的代码需要进行整理、抽象和资源释放(各种流)等。

下次分享添加水印的几种方式

你可能感兴趣的:(java,itext)