前言

在网上找了两天…没有一个能成事的,要不就是pdf打不开,要不就是根本下载不了…所以自己结合众多博文自己整理了一下;
注:用这个方法百分百能导出,是百分百,所以用过之后导不出来或有问题的记得联系我或者留言,我工作日每天都会看csdn,一定会及时回复的
注:文中的字体资源已分享到百度网盘
链接:https://pan.baidu.com/s/11yzNc8E025rtDGBV9ahKyg
提取码:gidf

一、编写pdf模板

推荐大家用Adobe工具编辑pdf模板,(已压缩打包到资源中,可自行下载)

1.首先打开pdf,选择更多工具

Java pdfbox生成pdf java根据pdf模板生成pdf_java

2. 选择准备表单

Java pdfbox生成pdf java根据pdf模板生成pdf_表单_02

3.编写自己的表单

Java pdfbox生成pdf java根据pdf模板生成pdf_表单_03


第一大步没啥好说的,就是基本流程,网上也能搜到,都是一样的,所以不过多介绍;

二、保存后,编写工具类,(直接复制过去就行了)

1.工具类

/**
     * 利用模板生成pdf导出
     */
    public static void pdfExportInfo(Map<String, String> dataMap,HttpServletResponse response) {
        // 模板路径
        String templatePath = "G:\\BaiduSyncdisk\\模板.pdf";

        // 生成导出PDF的文件名称
        String fileName = "test.pdf";

        OutputStream out = null;
        ByteArrayOutputStream bos = null;
        PdfStamper stamper = null;
        PdfReader reader = null;
        try {
            // 读取PDF模板表单
            reader = new PdfReader(templatePath);
            // 字节数组流,用来缓存文件流
            bos = new ByteArrayOutputStream();
            // 根据模板表单生成一个新的PDF
            stamper = new PdfStamper(reader, bos);
            // 获取新生成的PDF表单
            AcroFields form = stamper.getAcroFields();
            // 给表单生成中文字体,这里采用系统字体,不设置的话,中文显示会有问题
            BaseFont font = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            form.addSubstitutionFont(font);
            // 遍历data,给pdf表单赋值
            for(String key : dataMap.keySet()){
                // 图片要单独处理
                if("img".equals(key)){
                    form.addSubstitutionFont(BaseFont.createFont("STSong-Light",
                            "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED));
                    //通过域名获取所在页和坐标,左下角为起点
                    int pageNo = form.getFieldPositions(key).get(0).page;
                    Rectangle signRect = form.getFieldPositions(key).get(0).position;
                    float x = signRect.getLeft();
                    float y = signRect.getBottom();
                    String studentImage = dataMap.get(key);
                    //根据路径或Url读取图片
                    Image image = Image.getInstance(studentImage);

                    //获取图片页面
                    PdfContentByte under = stamper.getOverContent(pageNo);
                    //图片大小自适应
                    image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                    //添加图片
                    image.setAbsolutePosition(x, y);
                    under.addImage(image);
                } else {
                    // 设置普通文本数据
                    form.setField(key, dataMap.get(key));
                }
            }
            // 表明该PDF不可修改
            stamper.setFormFlattening(true);
            // 关闭资源
            stamper.close();
            // 将ByteArray字节数组中的流输出到out中
            Document doc = new Document();

            // 保存到本地 todo 想保存本地就打开这里 把下面三行注释了
            //out = Files.newOutputStream(Paths.get(fileName));
            // 浏览器下载 todo 想浏览器就打开这里 把上面一行注释了
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
            out = response.getOutputStream();

            PdfCopy copy = new PdfCopy(doc, out);
            doc.open();
            PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
            copy.addPage(importPage);
            doc.close();
            System.out.println("*****************************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();
            }
        }
    }

2.调用(刚才模板里的字段拿出来,当做map的key,写入自己的value就可以了)

我这里仅做示范

/**
     * desc: 导出隔离单
     * author: 秋雨
     * date: 2022-09-22
     **/
    @RequestMapping(value = "exportGelidan")
    public void exportGelidan(EpidemicCtrlInvestigationPerson epidemicCtrlInvestigationPerson,HttpServletResponse response){
        Map<String,Object> map = new HashMap<>();
        Map<String,String> dataMap = new HashMap<>();
        //姓名
        dataMap.put("personName", epidemicCtrlInvestigationPerson.getPersonName());
        //来源地
        dataMap.put("startingPoint", epidemicCtrlInvestigationPerson.getStartingPoint());
        //隔离开始时间
        String quarantimeBeginYear = "";
        String quarantimeBeginMonth = "";
        String quarantimeBeginDay = "";
        dataMap.put("quarantimeBeginYear", quarantimeBeginYear);
        dataMap.put("quarantimeBeginMonth", quarantimeBeginMonth);
        dataMap.put("quarantimeBeginDay", quarantimeBeginDay);
        //隔离结束时间
        String quarantimeEndYear = "";
        String quarantimeEndMonth = "";
        String quarantimeEndDay = "";
        dataMap.put("quarantimeEndYear", quarantimeEndYear);
        dataMap.put("quarantimeEndMonth", quarantimeEndMonth);
        dataMap.put("quarantimeEndDay", quarantimeEndDay);
        //通知时间
        Date date = epidemicCtrlInvestigationPerson.getCreateBillTime();
        String year = new SimpleDateFormat("yyyy").format(date);
        String month = new SimpleDateFormat("M").format(date);
        String day = new SimpleDateFormat("d").format(date);
        dataMap.put("year", year);
        dataMap.put("month", month);
        dataMap.put("day", day);
        map.put("dataMap",dataMap);
        PdfUtil.pdfExportInfo(dataMap,response);
    }

以上就是全部了

导出的pdf展示

Java pdfbox生成pdf java根据pdf模板生成pdf_前端_04