Java基于模板导出PDF

引入依赖

   <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

模板制作

使用PDF工具创建表单工具
这里推荐使用《Adobe Acrobat DC》

示例代码


    public  void towritepdf(HttpServletResponse response){

        // 设置响应头
        response.setContentType("application/force-download");
        response.setHeader("Content-Disposition",
                "attachment;fileName=test-demo1.pdf");
        OutputStream out = null;
        ByteArrayOutputStream bos = null;
        PdfStamper stamper = null;
        PdfReader reader = null;
        try {
            // 保存到本地
            // out = new FileOutputStream(fileName);
            // 输出到浏览器端
            out = response.getOutputStream();
            // 读取PDF模板表单
            reader = new PdfReader("F:\\HTM_WorkSpace\\doc\\xkz-test-demo1.pdf");
            // 字节数组流,用来缓存文件流
            bos = new ByteArrayOutputStream();
            // 根据模板表单生成一个新的PDF
            stamper = new PdfStamper(reader, bos);
            // 获取新生成的PDF表单
            AcroFields form = stamper.getAcroFields();
            // 给表单生成中文字体,这里采用系统字体,不设置的话,中文显示会有问题
//            BaseFont font = BaseFont.createFont("宋体", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            form.addSubstitutionFont(font);
            // 装配数据
            Map<String, String> data = new HashMap<>(15);
            // 表单变量
            data.put("conunit", "测试");
            // 遍历data,给pdf表单赋值
            if (MapUtils.isNotEmpty(data)) {
                Iterator<Map.Entry<String, String>> iterator = data.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, String> next = iterator.next();
                    String key = next.getKey();
                    String value = next.getValue();

                    // 默认12号字体
                    float fontSize = 12f;
                    PdfString da = form.getFieldItem(key).getMerged(0).getAsString(PdfName.DA);
                    if (da != null) {
                        Object dab[] = AcroFields.splitDAelements(da.toUnicodeString());
                        if (dab[AcroFields.DA_SIZE] != null)
                            fontSize = ((Float)dab[AcroFields.DA_SIZE]).floatValue();
                    }

                    // 文本框宽度
                    Rectangle position = form.getFieldPositions(key).get(0).position;
                    float textBoxWidth = position.getWidth();
                    // 文本框高度
                    float textBoxHeight = position.getHeight();
                    // 文本单行行高
                    float ascent = font.getFontDescriptor(font.ASCENT,fontSize);
                    // baseFont渲染后的文字宽度
                    float textWidth = font.getWidthPoint(value, fontSize);

                    // 文本框高度只够写一行,并且文字宽度大于文本框宽度,则缩小字体
                    if (textBoxHeight < ascent * 1.6) {
                        while (textWidth > textBoxWidth) {
                            fontSize--;
                            textWidth = font.getWidthPoint(value, fontSize);
                        }
                    }
                    BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                    Font font1 = new Font(bf, 12, Font.UNDERLINE);


//Font font = FontFactory.getFont(FontFactory.COURIER, 20, Font.BOLD, BaseColor.RED);

                    AcroFields s = reader.getAcroFields();

// 设置加粗只能用这种方式

                    List<AcroFields.FieldPosition> multiLinePosition = s.getFieldPositions(key);

                    int page = multiLinePosition.get(0).page;

                    Rectangle rectangle = multiLinePosition.get(0).position;

                    float left = rectangle.getLeft();

                    float right = rectangle.getRight();

                    float top = rectangle.getTop();

                    float bottom = rectangle.getBottom();

                    PdfContentByte pdfContentByte = stamper.getOverContent(page);

                    ColumnText columnText = new ColumnText(pdfContentByte);

                    Rectangle r = new Rectangle(left, bottom, right, top);

                    columnText.setSimpleColumn(r);

                    Chunk chunk = new Chunk("测试");

                    Paragraph paragraph = new Paragraph(12, chunk);

                    columnText.addText(paragraph);

                    // 设置字体,如果不设置添加的中文将无法显示

                    paragraph.setFont(font1);

                    columnText.addElement(paragraph);

                    columnText.go();
                }
            }

            // 表明该PDF不可修改
            stamper.setFormFlattening(true);
            // 关闭资源
            stamper.close();
            // 将ByteArray字节数组中的流输出到out中(即输出到浏览器)
            Document doc = new Document();
            PdfCopy copy = new PdfCopy(doc, out);
            doc.open();
            PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
            copy.addPage(importPage);
            doc.close();
            log.info("*****************************PDF导出成功*********************************");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (out != null) {
                    out.flush();
                    out.close();
                }
                if (reader != null) {
                    reader.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
posted @ 2022-06-23 15:02  博客-涛  阅读(107)  评论(0编辑  收藏  举报  来源