利用Adobe Acrobat DC制作pdf模板后,使用java直接生成pdf至本地指定路径或导出pdf文件

利用Adobe Acrobat DC制作pdf模板后,使用java直接生成pdf至本地指定路径或导出pdf文件,第1张

利用Adobe Acrobat DC制作pdf模板后,使用java直接生成pdf至本地指定路径或导出pdf文件

参考文章来源:
springboot+itextpdf按模板生成PDF文件及在线下载PDF文件
JAVA根据模板生成PDF文件并导出

java将字符串按照指定长度分割成字符串数组

感谢上述博主大大,救我一命~~~

我的系统环境:win10、IDEA、jdk1.8

一、Adobe Acrobat DC的下载

百度链接:链接:https://pan.baidu.com/s/1RSV8D6kXDbWeV2owgw2Zyg
提取码:f8p8
可自取。

二、模板准备

1、在word中画好模板,另存为pdf格式

我生成的pdf模板如下图所示。

2、打开软件:Adobe Acrobat DC

页面如下图所示,选择【工具】–【准备表单】

将上述pdf文件放入这里

进入编辑表单页面,编辑字段(此字段名需和程序中字段名保持一致)。我的编辑如下图所示。

由于在【备注】这一字段中,我们的要求是文字带下划线的那种,且备注文字可能会有些长,因此我在这里设置成这样,我的思路如下:
1、在Adobe Acrobat DC中设置了bz-line1、bz-line2、bz-line3三个文本域,并分别设置其属性(双击该域即可,文字大小样式等都可以设置)。如下图所示:

2、程序中,读取数据(字符串类型),按固定长度对字符串进行截取并循环放入bz-line1、bz-line2、bz-line3中。后面在程序里我会展示我使用的笨方法。。。。

3、其实。。如果没有要求带下划线的话,完全可以直接在【属性】中勾选上【多行】即可实现多文字的换行。

3、保存编辑好的模板

三、java实现

1、添加Maven依赖

          
		  
		      com.itextpdf
		      itextpdf
		      5.5.13
		  
		  
		  
		      com.itextpdf
		      itext-asian
		      5.2.0
		  

2、直接生成pdf至本地指定路径

(1)、pdfUtils类

public class PdfUtils {

    private final static Logger log = LoggerFactory.getLogger(PdfUtils.class);

    // 利用模板生成pdf,这将直接保存到指定路径
    public static void pdfout(Map o,String templatePath,String newPDFPath) {

        PdfReader reader;
        FileOutputStream out=null;
        ByteArrayOutputStream bos=null;
        PdfStamper stamper;
        try {
        	//系统字体
            String prefixFont = "";
            String os = System.getProperties().getProperty("os.name");
            if (os.startsWith("win") || os.startsWith("Win")) {
                prefixFont = "C:\Windows\Fonts" + File.separator;
            } else {
                prefixFont = "/usr/share/fonts/chinese" + File.separator;
            }
            //必须加“,0”或“,1”,否则会报错:com.itextpdf.text.documentException: Font 'C:WindowsFontssimsun.ttc' with 'Identity-H' is not recognized.
            baseFont bf = baseFont.createFont(prefixFont + "simsun.ttc,0" , baseFont.IDENTITY_H, baseFont.EMBEDDED);

            out = new FileOutputStream(newPDFPath);// 输出流
            reader = new PdfReader(templatePath);// 读取pdf模板
            bos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, bos);
            AcroFields form = stamper.getAcroFields();
            //文字类的内容处理
            Map datemap = (Map)o.get("datemap");
            form.addSubstitutionFont(bf);
            for(String key : datemap.keySet()){
                //为了文字可以有下划线,并且换行,控制每行字数,当字数超过时,将剩余文字填充至下一备选域
                if ("hzbz".equals(key)){
                    String hzbz = datemap.get(key);
                    String[] hzbzArray = stringToStringArray(hzbz,24);

                    for(int i = 0; i < hzbzArray.length; i++){
                        String fkey = "hzbz-line" + (i+1);
                        form.setField(fkey,hzbzArray[i]);
                    }

                }else if("bz".equals(key)){

                    String bz = datemap.get(key);
                    String[] bzArray = stringToStringArray(bz,24);

                    for(int i = 0; i < bzArray.length; i++){
                        String fkey = "bz-line" + (i+1);
                        form.setField(fkey,bzArray[i]);
                    }

                }else{
                    String value = datemap.get(key);
                    form.setField(key,value);
                }

            }
            //图片类的内容处理
            Map imgmap = (Map)o.get("imgmap");
            for(String key : imgmap.keySet()) {
                Image value = imgmap.get(key);
                //String imgpath = value;
                Image image = value;
                int pageNo = form.getFieldPositions(key).get(0).page;
                Rectangle signRect = form.getFieldPositions(key).get(0).position;
                float x = signRect.getLeft();
                float y = signRect.getBottom();
                //根据路径读取图片
                //Image image = Image.getInstance(imgpath);
                //获取图片页面
                PdfContentByte under = stamper.getOverContent(pageNo);
                //图片大小自适应
                image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                //添加图片
                image.setAbsolutePosition(x, y);
                under.addImage(image);
            }
            stamper.setFormFlattening(true);// 如果为false,生成的PDF文件可以编辑,如果为true,生成的PDF文件不可以编辑
            stamper.close();
            document doc = new document(PageSize.A4, 50, 40, 40, 50);
            PdfCopy copy = new PdfCopy(doc, out);
            doc.open();

            //form.getTotalRevisions();
            int pages= stamper.getReader().getNumberOfPages();
            for(int i=1;i<=pages;i++){
                PdfimportedPage importPage = copy.getimportedPage(new PdfReader(bos.toByteArray()), i);
                copy.addPage(importPage);
            }
            doc.close();
        } catch (IOException e) {
            log.error("pdfout",e);
        } catch (documentException e) {
            log.error("pdfout",e);
        }finally {
            if(out!=null){
                try{
                    out.close();
                }catch(Exception e){

                }
            }
            if(bos!=null){
                try{
                    bos.close();
                }catch(Exception e){

                }

            }

        }
    }

    // 将字符串按照指定长度分割成字符串数组
    public static String[] stringToStringArray(String src, int length) {
        //检查参数是否合法
        if (null == src || src.equals("")) {
            return null;
        }

        if (length <= 0) {
            return null;
        }
        int n = (src.length() + length - 1) / length; //获取整个字符串可以被切割成字符子串的个数
        String[] split = new String[n];
        for (int i = 0; i < n; i++) {
            if (i < (n - 1)) {
                split[i] = src.substring(i * length, (i + 1) * length);
            } else {
                split[i] = src.substring(i * length);
            }
        }
        return split;
    }

    public static  byte[] inputstream2Bytes(InputStream inStream)  throws IOException{
        byte[] in_b = null;
        try{
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100]; //buff用于存放循环读取的临时数据
            int rc = 0;
            while ((rc = inStream.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            in_b = swapStream.toByteArray(); //in_b为转换之后的结果

        }catch(Exception e){
            log.error("inputstream2Bytes",e);
        }finally {
            inStream.close();
        }
        return in_b;
    }

    
    public static InputStream file2InputStream(File file)  throws IOException{
        return new FileInputStream(file);
    }

(2)、controller层

@Controller
@RequestMapping("/pdf")
public class PdfController {

    @PostMapping("/createPdf")
    @ResponseBody
    public DataObject CreatePdf() throws AppException {

        //1、调用数据库,获取数据
		//此处写读取数据的代码
		
        //2、将数据存为key-value
        //存文字信息
        Map map = new HashMap();
        //存图像信息
        Map mapI = new HashMap();
        map.put("name","田XX");
        map.put("sex","女");
        map.put("grbh","123456789010");
        map.put("sfzh","000000000000000000");
        map.put("rylb","啊哦");
        map.put("time1","2021-9-27");
        map.put("ddyy1","啊哦");
        map.put("time2","");
        map.put("ddyy2","");
        map.put("hzbz","有的人一生默默无闻,有的人一生轰轰烈烈,甚至千古流芳,为什么会这样?因为默默无闻的人只是满足于现状,而不去想怎么轰轰烈烈过一生,不要求自己,去做");
        map.put("bz","有的人一生默默无闻,有的人一生轰轰烈烈,甚至千古流芳,为什么会这样?因为默默无闻的人只是满足于现状,而不去想怎么轰轰烈烈过一生,不要求自己,去做");
        try{
            //图片路径
            File pic_file = new File("F:\1555074510295049.jpg");
            Image pic_image = Image.getInstance(inputstream2Bytes(file2InputStream(pic_file)));
            mapI.put("pic",pic_image);
        }catch(Exception e){
        }

        Map o=new HashMap();
        o.put("datemap",map);
        o.put("imgmap",mapI);

        // 模板路径
        String templatePath = "/meta-INF/resources/static/template/template.pdf";
        // 生成的新文件路径
        String newPDFPath = "F:\template_sc.pdf";
        pdfout(o,templatePath,newPDFPath);
        return DataObject.getInstance();
    }
}

(3)前端入口

layui.sight.ajaxRequest({
     type : 'post',
     async : true,
     url : layui.sight.compileUrl('${rc.contextPath}/pdf/CreatePdf'),
     data : [],
     callback : function(data) {
         alert("成功!")
     },
     failedCallback : function(data) {}
});

3、导出pdf

(1)pdfUtils类

public class PdfUtils {

    private final static Logger log = LoggerFactory.getLogger(PdfUtils.class);

    
    public static void pdfExport(Map o, HttpServletResponse response) {

        // 模板路径
        String templatePath = "/meta-INF/resources/static/template/template.pdf";

        File file = new File(templatePath);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        PdfReader reader;
        ByteArrayOutputStream bos;
        PdfStamper stamper;
        OutputStream out = null;
        try {
            baseFont bf = baseFont.createFont("C:/Windows/Fonts/simfang.ttf", baseFont.IDENTITY_H, baseFont.EMBEDDED);
            // 输出流
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + URLEncoder.encode("template_scsc.pdf", "UTF-8"));
            out = new BufferedOutputStream(response.getOutputStream());
            // 读取pdf模板
            reader = new PdfReader(templatePath);
            bos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, bos);
            AcroFields form = stamper.getAcroFields();
            //文字类的内容处理
            Map datemap = (Map)o.get("datemap");
            form.addSubstitutionFont(bf);
            for(String key : datemap.keySet()){
                //为了文字可以有下划线,并且换行,控制每行字数,当字数超过时,将剩余文字填充至下一备选域
                if ("hzbz".equals(key)){
                    String hzbz = datemap.get(key);
                    String[] hzbzArray = stringToStringArray(hzbz,24);

                    for(int i = 0; i < hzbzArray.length; i++){
                        String fkey = "hzbz-line" + (i+1);
                        form.setField(fkey,hzbzArray[i]);
                    }

                }else if("bz".equals(key)){

                    String bz = datemap.get(key);
                    String[] bzArray = stringToStringArray(bz,24);

                    for(int i = 0; i < bzArray.length; i++){
                        String fkey = "bz-line" + (i+1);
                        form.setField(fkey,bzArray[i]);
                    }

                }else{
                    String value = datemap.get(key);
                    form.setField(key,value);
                }

            }
            //图片类的内容处理
            Map imgmap = (Map)o.get("imgmap");
            for(String key : imgmap.keySet()) {
                Image value = imgmap.get(key);
                //String imgpath = value;
                Image image = value;
                int pageNo = form.getFieldPositions(key).get(0).page;
                Rectangle signRect = form.getFieldPositions(key).get(0).position;
                float x = signRect.getLeft();
                float y = signRect.getBottom();
                //根据路径读取图片
                //Image image = Image.getInstance(imgpath);
                //获取图片页面
                PdfContentByte under = stamper.getOverContent(pageNo);
                //图片大小自适应
                image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                //添加图片
                image.setAbsolutePosition(x, y);
                under.addImage(image);
            }
            stamper.setFormFlattening(true);
            stamper.close();
            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();

        } catch (IOException | documentException e) {
            System.out.println(e);
        } finally {
            try {
                assert out != null;
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 将字符串按照指定长度分割成字符串数组
    public static String[] stringToStringArray(String src, int length) {
        //检查参数是否合法
        if (null == src || src.equals("")) {
            return null;
        }

        if (length <= 0) {
            return null;
        }
        int n = (src.length() + length - 1) / length; //获取整个字符串可以被切割成字符子串的个数
        String[] split = new String[n];
        for (int i = 0; i < n; i++) {
            if (i < (n - 1)) {
                split[i] = src.substring(i * length, (i + 1) * length);
            } else {
                split[i] = src.substring(i * length);
            }
        }
        return split;
    }

    public static  byte[] inputstream2Bytes(InputStream inStream)  throws IOException{
        byte[] in_b = null;
        try{
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100]; //buff用于存放循环读取的临时数据
            int rc = 0;
            while ((rc = inStream.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            in_b = swapStream.toByteArray(); //in_b为转换之后的结果

        }catch(Exception e){
            log.error("inputstream2Bytes",e);
        }finally {
            inStream.close();
        }
        return in_b;
    }

    
    public static InputStream file2InputStream(File file)  throws IOException{
        return new FileInputStream(file);
    }

(2)、controller层

@Controller
@RequestMapping("/pdf")
public class PdfController {

    @RequestMapping("/exportPdf")
    public void exportPdf(HttpServletRequest request, HttpServletResponse response) throws AppException {
        
        //调用数据库,获取数据

        //将数据存为key-value
        //存文字信息
        Map map = new HashMap();
        //存图像信息
        Map mapI = new HashMap();
        map.put("name","田XX");
        map.put("sex","女");
        map.put("grbh","12345678910");
        map.put("sfzh","00000000000000000");
        map.put("rylb","啊哦");
        map.put("time1","2021-9-27");
        map.put("ddyy1","啊哦");
        map.put("time2","");
        map.put("ddyy2","");
        map.put("hzbz","有的人一生默默无闻,有的人一生轰轰烈烈,甚至千古流芳,为什么会这样?因为默默无闻的人只是满足于现状,而不去想怎么轰轰烈烈过一生,不要求自己,去做");
        map.put("bz","有的人一生默默无闻,有的人一生轰轰烈烈,甚至千古流芳,为什么会这样?因为默默无闻的人只是满足于现状,而不去想怎么轰轰烈烈过一生,不要求自己,去做");
        try{
            //图片路径
            File pic_file = new File("F:\1555074510295049.jpg");
            Image pic_image = Image.getInstance(inputstream2Bytes(file2InputStream(pic_file)));
            mapI.put("pic",pic_image);
        }catch(Exception e){
        }

        Map o=new HashMap();
        o.put("datemap",map);
        o.put("imgmap",mapI);

        pdfExport(o,response);
    }
}

(3)前端入口

function down(){
    var url = layui.sight.compileUrl('${rc.contextPath}/pdf/exportPdf');
    window.open(encodeURI(url));
}
四、最终效果


图片选的不太好。。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/zaji/5597863.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存