Java uses itext to fill pdf template text and pictures, and make the filled template content vertically and horizontally centered

1. Background

Due to business needs, I need to generate a PDF report from part of the program data for download and browsing

2. Implementation method

  1. Design a pdf template, you can edit the template through pdf editing tools, and pdf editors that support editing forms on the market can be used, such as Adobe Acrobat DC, Wondershare PDF, QuickPDF, etc.
  2. Set the corresponding name of the form cell through form editing, and use it for subsequent program assignment
    insert image description here
  3. You can set the text to be centered horizontally (but the current programs do not support vertical centering, if you want to achieve it later, you need to start with the program)
    insert image description here
  4. After setting the text, you can start writing the program assignment (core code)
  //创建A4大小的文档
  Document document = new Document(PageSize.A4);
        document.open();
        //读取现有模板内容(templateFile为模板路径)
        PdfReader reader = new PdfReader(FileUtil.path(templateFile));
        //创建输出流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //实例化PdfStamper准备编辑pdf内容
        PdfStamper ps = new PdfStamper(reader, bos);
        //获取表单所有元素
        AcroFields fields = ps.getAcroFields();
        //设置具体字体格式编码,不设置的话中文可能会不显示
        BaseFont baseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        /添加替换元素
        fields.addSubstitutionFont(baseFont);
		//data是一个Map<String,String> 主要存储 key 表单模板中的单元格名 value为想要赋的值,遍历
        for (String key : data.keySet()) {
    
    
            String value = data.get(key);
            //个人逻辑,参考即可,对于特定的表单元素设置不同的字体格式大小
            if("r_game".equals(key)) {
    
    
            //设置格式
                fields.setFieldProperty(key, "textsize", 35f, null);
            }else if("i_title".equals(key)) {
    
    
                fields.setFieldProperty(key, "textsize", 20f, null);
            }else if ("r_image".equals(key)){
    
    
                if (!StringUtils.isEmpty(value)){
    
    
                //设置添加图片
                    addImageToPdf(fields, ps,value);
                    continue;
                }
            }else if ("r_project_name".equals(key)||"r_header".equals(key)||"r_appraisal".equals(key)){
    
    
            //将文本垂直居中添加
                addTextToPdfCenter(fields,ps,value,key,baseFont);
                continue;
            }
            else {
    
    
                fields.setFieldProperty(key, "textsize", defaultSize, null);
            }
            fields.setField(key, value);
        }
		//生成的文档可编辑
        ps.setFormFlattening(true);
        //关闭操作
        ps.close();
        //将编辑后的文件输出到outputFile路径下
        OutputStream fos = new FileOutputStream(FileUtil.path(outputFile));
        fos.write(bos.toByteArray());
        bos.close();
        fos.close();
        document.close();
  1. Image Population to Table Template
 private static void addImageToPdf(AcroFields form, PdfStamper stamper, String filePath) throws DocumentException, IOException {
    
    

        // 通过域名获取所在页和坐标,左下角为起点
        int pageNo = form.getFieldPositions("r_image").get(0).page;
        Rectangle signRect = form.getFieldPositions("r_image").get(0).position;
        float x = signRect.getLeft()+signRect.getRight();
        float y = signRect.getTop();

        // 读图片
        Image image = Image.getInstance(filePath);
        // 获取操作的页面
        PdfContentByte under = stamper.getOverContent(pageNo);
        // 根据域的大小缩放图片
        image.scaleToFit(signRect.getWidth()/4, signRect.getHeight()/4);
        // 添加图片并设置位置(个人通过此设置使得图片垂直水平居中,可参考,具体情况已实际为准)
        image.setAbsolutePosition(x/2-image.getWidth()/2, y/2+image.getHeight());
        under.addImage(image);
    }
  1. The text is not vertically centered as follows
    insert image description here

Center text vertically

Vertically center by getting the template position and then refactoring the form cells

  private static void addTextToPdfCenter(AcroFields form, PdfStamper stamper, String text,String fieldName,BaseFont baseFont){
    
    
        // 通过模板表单单元格名获取所在页和坐标,左下角为起点
        int pageNo = form.getFieldPositions(fieldName).get(0).page;
        Rectangle signRect = form.getFieldPositions(fieldName).get(0).position;
        // 获取操作的页面
        PdfContentByte contentByte = stamper.getOverContent(pageNo);
        //创建表单
        PdfPTable table = new PdfPTable(1);
        //获取当前模板表单宽度
        float totalWidth = signRect.getRight() - signRect.getLeft() - 1;
        //设置新表单宽度
        table.setTotalWidth(totalWidth);
        //设置中文格式
        Font font = new Font(baseFont);
        //设置单元格格式
        PdfPCell cell = new PdfPCell(new Phrase(text,font));
        //设置单元格高度
        cell.setFixedHeight(signRect.getTop()-signRect.getBottom()-1);
        cell.setBorderWidth(0);
        //设置垂直居中
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        //设置水平居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        //添加到表单中
        table.addCell(cell);
        //写入pdf
        table.writeSelectedRows(0, -1, signRect.getLeft(), signRect.getTop(), contentByte);
    }

The effect is as follows
insert image description here

Guess you like

Origin blog.csdn.net/weixin_43288999/article/details/119185020