• java之数据填充PDF模板


    声明:由于业务场景需要,所以根据一个网友的完成的。

    1、既然要使用PDF模板填充,那么就需要制作PDF模板,可以使用Adobe Acrobat DC,下载地址https://carrot.ctfile.com/dir/11269771-27158812-194d66/29433907/ (使用特别破解版),安装步骤就省略了。

    2、开始制作模板

      a)使用wps制作一个表格,并转为PDF文件保存

      

      b)使用Adobe Acrobat DC打开保存的PDF文件,然后搜索 "准备表单" ,点击 ”准备表单“,然后出来表单域

    3、程序部分

      a)依赖

         <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.4</version>
            </dependency>
    
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.10</version>
            </dependency>
    
            <!-- itextpdf 依赖包start -->
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>5.5.10</version>
            </dependency>
    
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itext-asian</artifactId>
                <version>5.2.0</version>
            </dependency>
            <!-- itextpdf 依赖包end -->
    
            <!--pdf 转图片 start -->
            <dependency>
                <groupId>org.apache.pdfbox</groupId>
                <artifactId>pdfbox</artifactId>
                <version>2.0.11</version>
            </dependency>
    
            <dependency>
                <groupId>net.coobird</groupId>
                <artifactId>thumbnailator</artifactId>
                <version>0.4.2</version>
            </dependency>
            <!--pdf 转图片 end -->

      b)工具类 ImageThumbUtils,该类主要是用于将pdf转为图片,如果不需要可以不添加

    package com.yangwj.demo.controller;
    
    import net.coobird.thumbnailator.Thumbnails;
    import net.coobird.thumbnailator.geometry.Positions;
    
    import javax.imageio.ImageIO;
    import java.io.ByteArrayInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    
    /**
     * 图片缩略、裁剪、添加水印。
     */
    public class ImageThumbUtils {
    
        /**
         * 缩略图片,图片质量为源图的80%
         *
         * @param originalImgPath
         *            源图片存储路径
         * @param w
         *            图片压缩后的宽度
         * @param h
         *            图片压缩后的高度
         * @param targetImgPath
         *            缩略图的存放路径
         */
        public static void thumbImage(String originalImgPath, int w, int h, String targetImgPath) throws Exception {
            thumbImage(new FileInputStream(originalImgPath), w, h, targetImgPath, 0.8);
        }
    
        /**
         * 缩略图片,图片质量为源图的80%
         *
         * @param originalImgData
         *            源图片字节数
         * @param w
         *            图片压缩后的宽度
         * @param h
         *            图片压缩后的高度
         * @param targetImgPath
         *            缩略图的存放路径
         */
        public static void thumbImage(byte[] originalImgData, int w, int h, String targetImgPath) throws Exception {
            thumbImage(new ByteArrayInputStream(originalImgData), w, h, targetImgPath, 0.8);
        }
    
        /**
         * 按比例压缩文件
         * @param originalImgData 源文件
         * @param compressQalitiy 压缩比例
         * @param targetImgPath 目标路径
         */
        public static void thumbImage(byte[] originalImgData, double compressQalitiy, String targetImgPath) throws Exception {
            Thumbnails.of(new ByteArrayInputStream(originalImgData)).scale(1f).outputQuality(compressQalitiy).toFile(targetImgPath);
        }
    
        /**
         * 按尺寸比例缩略
         *
         * @param originalInputSteam
         *            源图输入流
         * @param w
         *            缩略宽
         * @param h
         *            缩略高
         * @param targetImgPath
         *            缩略图存储路径
         * @param compressQalitiy
         *            缩略质量比例,0~1之间的数
         */
        public static void thumbImage(InputStream originalInputSteam, int w, int h, String targetImgPath, double compressQalitiy) throws Exception {
            thumbImage(originalInputSteam, w, h, targetImgPath, compressQalitiy, true);
        }
    
        /**
         *
         * @param originalImgInputSteam
         *            源图片输入流
         * @param w
         *            图片压缩后的宽度
         * @param h
         *            图片压缩后的高度
         * @param targetImgPath
         *            缩略图的存放路径
         * @param compressQalitiy
         *            压缩比例,0~1之间的double数字
         * @param keepAspectRatio
         *            是否保持等比例压缩,是true,不是false
         */
        public static void thumbImage(InputStream originalImgInputSteam, int w, int h, String targetImgPath, double compressQalitiy,
                                      boolean keepAspectRatio) throws Exception {
            Thumbnails.of(originalImgInputSteam).size(w, h).outputQuality(Double.valueOf(compressQalitiy)).keepAspectRatio(true).toFile(targetImgPath);
        }
    
        /**
         * 图片裁剪
         *
         * @param originalImgPath
         *            源图片路径
         * @param targetImgPath
         *            新图片路径
         * @param position
         *            位置 0正中间,1中间左边,2中间右边,3底部中间,4底部左边,5底部右边,6顶部中间,7顶部左边,8顶部右边,
         *            其他为默认正中间
         * @param w
         *            裁剪宽度
         * @param h
         *            裁剪高度
         * @throws Exception
         */
        public static void crop(String originalImgPath, int position, int w, int h, String targetImgPath) throws Exception {
            Thumbnails.of(originalImgPath).sourceRegion(getPositions(position), w, h).size(w, h).outputQuality(1).toFile(targetImgPath);
        }
    
        /**
         * 给图片添加水印
         *
         * @param originalImgPath
         *            将被添加水印图片 路径
         * @param targetImgPath
         *            含有水印的新图片路径
         * @param watermarkImgPath
         *            水印图片
         * @param position
         *            位置 0正中间,1中间左边,2中间右边,3底部中间,4底部左边,5底部右边,6顶部中间,7顶部左边,8顶部右边,
         *            其他为默认正中间
         * @param opacity
         *            不透明度,取0~1之间的float数字,0完全透明,1完全不透明
         * @throws Exception
         */
        public static void watermark(String originalImgPath, String watermarkImgPath, int position, float opacity, String targetImgPath)
                throws Exception {
            Thumbnails.of(originalImgPath).watermark(getPositions(position), ImageIO.read(new File(watermarkImgPath)), opacity).scale(1.0)
                    .outputQuality(1).toFile(targetImgPath);
        }
    
        private static Positions getPositions(int position) {
            Positions p = Positions.CENTER;
            switch (position) {
                case 0: {
                    p = Positions.CENTER;
                    break;
                }
                case 1: {
                    p = Positions.CENTER_LEFT;
                    break;
                }
                case 2: {
                    p = Positions.CENTER_RIGHT;
                    break;
                }
                case 3: {
                    p = Positions.BOTTOM_CENTER;
                    break;
                }
                case 4: {
                    p = Positions.BOTTOM_LEFT;
                    break;
                }
                case 5: {
                    p = Positions.BOTTOM_RIGHT;
                    break;
                }
                case 6: {
                    p = Positions.TOP_CENTER;
                    break;
                }
                case 7: {
                    p = Positions.TOP_LEFT;
                    break;
                }
                case 8: {
                    p = Positions.TOP_RIGHT;
                    break;
                }
                default: {
                    p = Positions.CENTER;
                    break;
                }
            }
            return p;
        }
    
        public static void main(String[] args) throws Exception {
            thumbImage("d:/pdf/1.jpg", 600, 600, "d:/pdf/2.jpg");
            crop("d:/pdf/1.jpg", 7, 200, 300, "d:/pdf/2.jpg");
            watermark("d:/pdf/1.jpg", "d:/pdf/2.jpg", 7, 1, "d:/pdf/3.jpg");
        }
    }
    View Code

      c)实现数据填充PDF模板

    package com.yangwj.demo.controller;
    
    import com.itextpdf.text.Document;
    import com.itextpdf.text.pdf.*;
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.io.IOUtils;
    import org.apache.pdfbox.pdmodel.PDDocument;
    import org.apache.pdfbox.rendering.PDFRenderer;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.*;
    import java.util.List;
    
    /**
     * Description: PdfUtils <br>
     * 依赖的包:itextpdf    itext-asian
     * commons-io,commons-codec
     * @author mk
     * @Date 2018-11-2 14:32 <br>
     * @Param
     * @return
     */
    public class PdfUtils {
    
    
        public static void main(String[] args) throws IOException {
            HashMap map = new HashMap<String, String>();
            map.put("name","杨杰");
            map.put("sex","");
            map.put("age","27");
            map.put("phone","15521331");
            map.put("email","812406fdf@qq.com");
            map.put("idCard","4305223243434332");
            map.put("hobby","跑步");
            map.put("time","2019年5月22日");
    //        String path = PdfUtils.class.getResource("/template").getPath();
    //        System.out.println("path:"+path);
    //        String sourceFile = path + File.separator + "test.pdf";
            String sourceFile = "C:\Users\yangwj\Desktop\test.pdf";
            String targetFile = "C:\Users\yangwj\Desktop\test_fill.pdf";
           genPdf(map,sourceFile,targetFile);
    
    //        System.out.println("获取pdf表单中的fieldNames:"+getTemplateFileFieldNames(sourceFile));
    //        System.out.println("读取文件数组:"+fileBuff(sourceFile));
    //        System.out.println("pdf转图片:"+pdf2Img(new File(targetFile),imageFilePath));
        }
    
        private static void genPdf(HashMap map, String sourceFile, String targetFile) throws IOException {
            File templateFile = new File(sourceFile);
            fillParam(map, FileUtils.readFileToByteArray(templateFile), targetFile);
        }
    
        /**
         * Description: 使用map中的参数填充pdf,map中的key和pdf表单中的field对应 <br>
         * @author mk
         * @Date 2018-11-2 15:21 <br>
         * @Param
         * @return
         */
        public static void fillParam(Map<String, String> fieldValueMap, byte[] file, String contractFileName) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(contractFileName);
                PdfReader reader = null;
                PdfStamper stamper = null;
                BaseFont base = null;
                try {
                    reader = new PdfReader(file);
                    stamper = new PdfStamper(reader, fos);
                    stamper.setFormFlattening(true);
                    base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                    AcroFields acroFields = stamper.getAcroFields();
                    for (String key : acroFields.getFields().keySet()) {
                        acroFields.setFieldProperty(key, "textfont", base, null);
                        acroFields.setFieldProperty(key, "textsize", new Float(9), null);
                    }
                    if (fieldValueMap != null) {
                        for (String fieldName : fieldValueMap.keySet()) {
                            acroFields.setField(fieldName, fieldValueMap.get(fieldName));
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (stamper != null) {
                        try {
                            stamper.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    if (reader != null) {
                        reader.close();
                    }
                }
    
            } catch (Exception e) {
                System.out.println("填充参数异常");
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(fos);
            }
        }
    
        /**
         * Description: 获取pdf表单中的fieldNames<br>
         * @author mk
         * @Date 2018-11-2 15:21 <br>
         * @Param
         * @return
         */
        public static Set<String> getTemplateFileFieldNames(String pdfFileName) {
            Set<String> fieldNames = new TreeSet<String>();
            PdfReader reader = null;
            try {
                reader = new PdfReader(pdfFileName);
                Set<String> keys = reader.getAcroFields().getFields().keySet();
                for (String key : keys) {
                    int lastIndexOf = key.lastIndexOf(".");
                    int lastIndexOf2 = key.lastIndexOf("[");
                    fieldNames.add(key.substring(lastIndexOf != -1 ? lastIndexOf + 1 : 0, lastIndexOf2 != -1 ? lastIndexOf2 : key.length()));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    reader.close();
                }
            }
    
            return fieldNames;
        }
    
    
        /**
         * Description: 读取文件数组<br>
         * @author mk
         * @Date 2018-11-2 15:21 <br>
         * @Param
         * @return
         */
        public static byte[] fileBuff(String filePath) throws IOException {
            File file = new File(filePath);
            long fileSize = file.length();
            if (fileSize > Integer.MAX_VALUE) {
                //System.out.println("file too big...");
                return null;
            }
            FileInputStream fi = new FileInputStream(file);
            byte[] file_buff = new byte[(int) fileSize];
            int offset = 0;
            int numRead = 0;
            while (offset < file_buff.length && (numRead = fi.read(file_buff, offset, file_buff.length - offset)) >= 0) {
                offset += numRead;
            }
            // 确保所有数据均被读取
            if (offset != file_buff.length) {
                throw new IOException("Could not completely read file " + file.getName());
            }
            fi.close();
            return file_buff;
        }
    
        /**
         * Description: 合并pdf <br>
         * @author mk
         * @Date 2018-11-2 15:21 <br>
         * @Param
         * @return
         */
        public static void mergePdfFiles(String[] files, String savepath) {
            Document document = null;
            try {
                document = new Document(); //默认A4大小
                PdfCopy copy = new PdfCopy(document, new FileOutputStream(savepath));
                document.open();
                for (int i = 0; i < files.length; i++) {
                    PdfReader reader = null;
                    try {
                        reader = new PdfReader(files[i]);
                        int n = reader.getNumberOfPages();
                        for (int j = 1; j <= n; j++) {
                            document.newPage();
                            PdfImportedPage page = copy.getImportedPage(reader, j);
                            copy.addPage(page);
                        }
                    } finally {
                        if (reader != null) {
                            reader.close();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭PDF文档流,OutputStream文件输出流也将在PDF文档流关闭方法内部关闭
                if (document != null) {
                    document.close();
                }
    
            }
        }
    
    
    
        /**
         * pdf转图片
         * @param file pdf
         * @return
         */
        public static boolean pdf2Img(File file,String imageFilePath) {
            try {
                //生成图片保存
                byte[] data = pdfToPic(PDDocument.load(file));
                File imageFile = new File(imageFilePath);
                ImageThumbUtils.thumbImage(data, 1, imageFilePath); //按比例压缩图片
                System.out.println("pdf转图片文件地址:" + imageFilePath);
                return true;
            } catch (Exception e) {
                System.out.println("pdf转图片异常:");
                e.printStackTrace();
            }
    
            return false;
        }
    
        /**
         * pdf转图片
         */
        private static byte[] pdfToPic(PDDocument pdDocument) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            List<BufferedImage> piclist = new ArrayList<BufferedImage>();
            try {
                PDFRenderer renderer = new PDFRenderer(pdDocument);
                for (int i = 0; i < pdDocument.getNumberOfPages(); i++) {//
                    // 0 表示第一页,300 表示转换 dpi,越大转换后越清晰,相对转换速度越慢
                    BufferedImage image = renderer.renderImageWithDPI(i, 108);
                    piclist.add(image);
                }
                // 总高度 总宽度 临时的高度 , 或保存偏移高度 临时的高度,主要保存每个高度
                int height = 0, width = 0, _height = 0, __height = 0,
                        // 图片的数量
                        picNum = piclist.size();
                // 保存每个文件的高度
                int[] heightArray = new int[picNum];
                // 保存图片流
                BufferedImage buffer = null;
                // 保存所有的图片的RGB
                List<int[]> imgRGB = new ArrayList<int[]>();
                // 保存一张图片中的RGB数据
                int[] _imgRGB;
                for (int i = 0; i < picNum; i++) {
                    buffer = piclist.get(i);
                    heightArray[i] = _height = buffer.getHeight();// 图片高度
                    if (i == 0) {
                        // 图片宽度
                        width = buffer.getWidth();
                    }
                    // 获取总高度
                    height += _height;
                    // 从图片中读取RGB
                    _imgRGB = new int[width * _height];
                    _imgRGB = buffer.getRGB(0, 0, width, _height, _imgRGB, 0, width);
                    imgRGB.add(_imgRGB);
                }
    
                // 设置偏移高度为0
                _height = 0;
                // 生成新图片
                BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                int[] lineRGB = new int[8 * width];
                int c = new Color(128, 128, 128).getRGB();
                for (int i = 0; i < lineRGB.length; i++) {
                    lineRGB[i] = c;
                }
                for (int i = 0; i < picNum; i++) {
                    __height = heightArray[i];
                    // 计算偏移高度
                    if (i != 0)
                        _height += __height;
                    imageResult.setRGB(0, _height, width, __height, imgRGB.get(i), 0, width); // 写入流中
    
                    // 模拟页分隔
                    if (i > 0) {
                        imageResult.setRGB(0, _height + 2, width, 8, lineRGB, 0, width);
                    }
                }
                // 写流
                ImageIO.write(imageResult, "jpg", baos);
            } catch (Exception e) {
                System.out.println("pdf转图片异常:");
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(baos);
                try {
                    pdDocument.close();
                } catch (Exception ignore) {
                }
            }
    
            return baos.toByteArray();
        }
    }
    View Code

     4、针对复选框的填充

    只需要在相应的字段(现金付费)设置值为"On"。

    5、针对属性值太长,可以对填充框进行换行

  • 相关阅读:
    PHP substr_compare() 函数
    Learn X in Y minutes
    类型和程序设计语言
    C++17尝鲜
    《Ensemble Methods: Foundations and Algorithms》
    周志华:“深”为什么重要,以及还有什么深的网络
    阿里毕玄:系统架构师如何做好系统设计?
    调用链监控:Dapper、Istio... etc.
    zz京东电商推荐系统实践
    zzPony.ai 的基础架构挑战与实践
  • 原文地址:https://www.cnblogs.com/ywjfx/p/10908316.html
Copyright © 2020-2023  润新知