Java usa itext para llenar el texto y las imágenes de la plantilla PDF, y hacer que el contenido de la plantilla llena esté centrado vertical y horizontalmente

1. Antecedentes

Debido a necesidades comerciales, necesito generar un informe en PDF a partir de parte de los datos del programa para descargar y navegar

2. Método de implementación

  1. Diseñe una plantilla de pdf, puede editar la plantilla a través de herramientas de edición de pdf y se pueden usar editores de pdf que admiten la edición de formularios en el mercado, como Adobe Acrobat DC, Wondershare PDF, QuickPDF, etc.
  2. Establezca el nombre correspondiente de la celda del formulario a través de la edición del formulario y utilícelo para la asignación posterior del programa
    inserte la descripción de la imagen aquí
  3. Puede configurar el texto para que se centre horizontalmente (pero los programas actuales no admiten el centrado vertical, si desea lograrlo más tarde, debe comenzar con el programa)
    inserte la descripción de la imagen aquí
  4. Después de configurar el texto, puede comenzar a escribir la asignación del programa (código principal)
  //创建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. Población de imagen a plantilla de tabla
 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. El texto no está centrado verticalmente de la siguiente manera
    inserte la descripción de la imagen aquí

Centrar el texto verticalmente

Centrar verticalmente obteniendo la posición de la plantilla y luego refactorizando las celdas del formulario

  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);
    }

El efecto es el siguiente
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_43288999/article/details/119185020
Recomendado
Clasificación