通过pdf模板,填充内容,生成pdf文件---JAVA
阅读原文时间:2023年07月10日阅读:4

1 概述

  我们通常会遇到需要生成某些固定格式,但是内容不同的文件,那么我们就可以使用⽤Adobe Acrobat DC来创建pdf模块,然后通过代码对模板进行填充,生成pdf文件

2 创建一个pdf模板文件

3 使⽤Adobe Acrobat DC打开PDF⽂件,来创建模板

还可以双击这个框框打开设置,设置其他属性

  

4 编码

package com.ruoyi.weixin.user.MyTest.Itext;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;

import javax.imageio.ImageIO;
import java.io.*;

/**
* @Classname ImageThumbUtil
* @Description TODO
* @Date 2022/5/6 0006 下午 4:34
* @Created by jcc
*/
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 originalImgData 源⽂件  
 \* @param compressQalitiy 压缩⽐例  
 \*/  
public static OutputStream thumbImage(byte\[\] originalImgData, double compressQalitiy) throws Exception {  
    OutputStream os = new ByteArrayOutputStream();  
    Thumbnails.of(new ByteArrayInputStream(originalImgData)).scale(1f).outputQuality(compressQalitiy).toOutputStream(os);  
    return os;  
}

/\*\*  
 \* 按尺⼨⽐例缩略  
 \*  
 \* @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");  
}  

}

/**
* @Classname PdfUtils
* @Description TODO
* @Date 2022/5/6 0006 下午 4:40
* @Created by jcc
*/
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

* 依赖的包:itextpdf itext-asian
* commons-io,commons-codec
* @author mk
* @Date 2018-11-2 14:32

* @Param
* @return
*/
public class PdfUtils {

public static void main(String\[\] args) throws IOException {  

      //注意,这里构建map,key和value都要是String
HashMap map = new HashMap();
     //姓名
map.put("customerAsex", "陈晓");
// 年龄
map.put("customerAage", "13");
// String path = PdfUtils.class.getResource("/template").getPath();
// System.out.println("path:"+path);
// String sourceFile = path + File.separator + "test.pdf";
//模板文件
String sourceFile = "C:\\Users\\Administrator\\Desktop\\muban.pdf";
//生成的pdf文件(自己随便定义)
String targetFile = "C:\\Users\\Administrator\\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));
}

/\*  
 \*  
 \* @Description TOOD  
 \* @param map      我们要填充的内容,key是pdf模板文本域的名称,value是要填充内容  
 \* @param sourceFile    模板文件路径  
 \* @param targetFile    生成的pdf文件路径  
 \* @return void  
 \* @date 2022/5/6 0006 下午 5:39  
 \* @author jcc  
 \*/  
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

* @author mk
* @Date 2018-11-2 15:21

* @Param
* @return
*/
public static Set getTemplateFileFieldNames(String pdfFileName) {
Set fieldNames = new TreeSet();
PdfReader reader = null;
try {
reader = new PdfReader(pdfFileName);
Set 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: 读取⽂件数组

* @author mk
* @Date 2018-11-2 15:21

* @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转图⽚
* pdf转图⽚
*/
private static byte[] pdfToPic(PDDocument pdDocument) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
List piclist = new ArrayList();
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 imgRGB = new ArrayList();
// 保存⼀张图⽚中的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();
}
}

  测试代码中,只填了customerAname和customerAage到map中,所以这里只填入了左边的姓名和年龄

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章