java操作pdf模板并添加动态集合列表数据

最近在做pdf模板时,遇到这么一个情况,一部分是固定数据-A,一部分是动态集合数据-B。

刚开始也没注意到会有动态数据,就设置pdf模板进行文本域处理,也是到后来对数据的时候才发现B是

动态数据,但是已经做完模板文本域处理了,不想再纯java生成pdf了。

于是就想能不能把动态数据放到最后,先对固定数据A按照模板填充数据生成临时pdf,然后把填充过数据的临时pdf和动态数据则动态拼接到最终pdf上。

第一步-----生成临时pdf:先把固定数据填充到pdf模板生成临时pdf

   /**
     * 填充pdf数据
     * @param inPath  pdf模板路径
     * @param outPath 填充数据的pdf路径
     * @param templateMap
     */
    public static void writePdfModel(String inPath, String outPath, HashMap<String, String> templateMap) {


        FileOutputStream fos = null;
        PdfReader reader = null;
        PdfStamper stamper = null;
        BaseFont base = null;
        try {
            byte[] file = FileUtils.readFileToByteArray(new File(inPath));

            fos = new FileOutputStream(outPath);
            reader = new PdfReader(file);
            stamper = new PdfStamper(reader, fos);
            stamper.setFormFlattening(true);
            //简体中文字体
            base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); 
        
            AcroFields acroFields = stamper.getAcroFields();
            for (String key : acroFields.getFields().keySet()) {
                acroFields.setFieldProperty(key, "textfont", base, null);
            }
            if (templateMap != null) {
                for (String fieldName : templateMap.keySet())
                {
                    if (StringUtils.isNotBlank(templateMap.get(fieldName)))
                    {
                        acroFields.setField(fieldName, templateMap.get(fieldName));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                stamper.close();
            } catch (DocumentException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            reader.close();
            IOUtils.closeQuietly(fos);
        }


    }

第二步----生成最终pdf:拿临时pdf和动态集合数据拼接成最终的pdf

有需要在页眉生成图片logo的可以使用 Header类,不需要生成则可以去除这个类

/**
 * 生成最终版本的pdf
 * @param outPath 已写入数据的临时pdf模板路径
 * @param finalPath 最终版本的pdf生成路径

 * @throws Exception
 */
public static void getFinalPdf(String outPath, String finalPath) {
    PdfReader reader = null;// 读取pdf模板
    Document document = null;
    PdfWriter writer = null;
    FileOutputStream outputStream =null;
    FileOutputStream fos = null;
    try {
        outputStream = new FileOutputStream(finalPath);
        reader = new PdfReader(outPath);
        Rectangle pageSize = reader.getPageSize(1);
        document = new Document(pageSize);
        writer = PdfWriter.getInstance(document, outputStream);


        document.open();
        PdfContentByte cbUnder = writer.getDirectContentUnder();
        PdfImportedPage pageTemplate = writer.getImportedPage(reader, 1);
        cbUnder.addTemplate(pageTemplate, 0, 0);
        //新创建一页来存放后面生成的表格
        document.newPage();

        //设置logo
        PdfPTable table=new PdfPTable(1);
        Header header = new Header(table);
        header.setTableHeader(writer);
        document.add(table);

        //页眉和table之间的间距
        Paragraph blank = new Paragraph(" ");
        document.add(blank);
       
		//填充动态集合数据填充
		List<对象> 集合1=new ArrayList();
        Paragraph paragraph = generatePdfATATable(集合1);
        document.add(paragraph);
        
    } catch (IOException e) {
        e.printStackTrace();
    } catch (DocumentException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        document.close();
        reader.close();
    }

}

/**
 * 生成pdf表格
 * @return
 * @see
 */
private static Paragraph generatePdfATATable(List<对象> 集合1) throws Exception {
    BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

    //浅色不加粗
    Font fontChinese1 = new Font(bfChinese, 11F, Font.NORMAL);// 五号
    //黑色加粗
    Font fontChinese = new Font(bfChinese, 11F, Font.BOLD);// 五号
    Paragraph ret = new Paragraph("用药情况:", fontChinese1);
    PdfPTable tableBox = new PdfPTable(4);
    tableBox.setWidths(new float[] { 0.5f, 0.5f, 0.5f,0.5f });// 每个单元格占多宽
    //设置总宽度
    tableBox.setWidthPercentage(95f);
    // 创建表格格式及内容
    
    tableBox.addCell(getCell(new Phrase("药物名称", fontChinese), false, 1, 1));
    tableBox.addCell(getCell(new Phrase("剂量", fontChinese), false, 1, 1));
    tableBox.addCell(getCell(new Phrase("用法", fontChinese), false, 1, 1));
    tableBox.addCell(getCell(new Phrase("频次", fontChinese), false, 1, 1));

    for (集合 ata : 集合1) {
        tableBox.addCell(getCell(new Phrase(ata.getA(), fontChinese1), false, 1, 1));
        tableBox.addCell(getCell(new Phrase(String.valueOf(ata.getB()), fontChinese1), false, 1, 1));
        tableBox.addCell(getCell(new Phrase(String.valueOf(ata.getC()), fontChinese1), false, 1, 1));
        tableBox.addCell(getCell(new Phrase(String.valueOf(ata.getD()), fontChinese1), false, 1, 1));
    }
    ret.add(tableBox);
    return ret;
}




/**
 *
 * 设置页眉信息;填充logo
 *
 */
private static class Header extends PdfPageEventHelper {
    public static PdfPTable header;

    public Header(PdfPTable header) {
        Header.header = header;
    }

    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        // 把页眉表格定位
        header.writeSelectedRows(0, -1, 30, 806, writer.getDirectContent());
    }

    /**
     * 设置页眉
     *
     * @param writer
     * @throws Exception
     */
    public void setTableHeader(PdfWriter writer) throws Exception {

      //  String filePath = HomeAssessmentPdfUtil.class.getResource("/static/file/pdflogo.png").getPath();


        URL url=Thread.currentThread().getContextClassLoader().getResource("static/file/pdflogo.png");


        PdfPTable table = new PdfPTable(1);
        table.setTotalWidth(530);
        PdfPCell cell = new PdfPCell();
        cell.setBorder(0);
        Image image01;
        image01 = Image.getInstance(url); // 图片自己传
        // image01.scaleAbsolute(355f, 10f);
        image01.setWidthPercentage(20);
        // cell.setPaddingLeft(30f);
        cell.setPaddingTop(-20f);
        cell.addElement(image01);
        //1 带下划线 0不带下划线
        cell.setBorderWidthBottom(0);
        table.addCell(cell);
        Header event = new Header(table);
        writer.setPageEvent(event);
    }
}

本来我的想法是在临时pdf上拼接动态集合数据而不是重新生成pdf,但是这样会把临时pdf数据给覆盖掉的一个效果。

好了,今天的分享到这结束了,有需要的可以自取代码。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

博客胡

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值