最近遇到需求,需要批量生成800+个证书,所以写了一个简单个工具,原理就是PDF表单,读取csv表格中的数据,然后批量生成,比较通用的一个工具,所以分享一下
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import java.io.*;
import java.util.*;
/**
* 生成证书
* 将表格另存为UTF-8编码的csv文件,若为其他编码请修改常量CHARSET_NAME,修改对应表头行数为表格对应表头行数运行即可,Windows系统的文件路径为C:\\User\\xxx\\xxx.csv格式,linux和Unix系统为/格式
*
* @author xuwei
*/
public class Main {
/**
* 设置文件编码格式,不对应的话会统计错误
*/
private static final String CHARSET_NAME = "UTF-8";
/**
* 表格路径
*/
private static final String CSV_FILE_OF_USER = "/Users/xuwei/Desktop/users.csv";
/**
* 证书模板路径
*/
private static final String CERTIFICATE_TEMPLATE = "/Users/xuwei/Desktop/结业证书第三季.pdf";
/**
* 输出文件夹路径
*/
private static final String PATH_OF_OUTPUT = "/Users/xuwei/Desktop/certificate/";
/**
* 输出文件名对应表头字段名
*/
private static final String FILE_NAME_OF_OUTPUT = "姓名";
/**
* 字体路径
*/
private static final String PATH_OF_FONT = "KaiTi.ttc,1";
/**
* 主函数
*
* @param args
*/
public static void main(String[] args) {
try (Scanner scanner = new Scanner(new File(CSV_FILE_OF_USER), CHARSET_NAME)) {
//读取表头
String[] header = scanner.nextLine().split(",");
while (scanner.hasNextLine()) {
String[] fields = scanner.nextLine().split(",");
String fileName = new Date().toString();
Map<String, String> data = new HashMap<>(header.length);
for (int i = 0; i < header.length && i < fields.length; ++i) {
if(FILE_NAME_OF_OUTPUT.equals(deleteUtf8Bom(header[i]))){
fileName = fields[i];
}
data.put(deleteUtf8Bom(header[i]), deleteUtf8Bom(fields[i]));
}
System.out.println("准备生成"+fileName+"的证书");
generateCertificate(data,PATH_OF_OUTPUT+"/"+fileName+".pdf");
}
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
}
/**
* 生成证书
* @param fields
* @param fileName
*/
public static void generateCertificate(Map<String,String> fields,String fileName) throws IOException, DocumentException {
//读取模板文件
PdfReader pdfReader = new PdfReader(CERTIFICATE_TEMPLATE);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//读取PDF模板内容
PdfStamper pdfStamper = new PdfStamper(pdfReader, byteArrayOutputStream);
pdfStamper.getUnderContent(1);
//使用项目下的自定义的中文字体
BaseFont baseFont = BaseFont.createFont(PATH_OF_FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//获取模板中的所有字段
AcroFields acroFields = pdfStamper.getAcroFields();
acroFields.addSubstitutionFont(baseFont);
for (String key : fields.keySet()){
acroFields.setField(key,fields.get(key));
}
//必须要调用这个,否则文档不会生成的
pdfStamper.setFormFlattening(true);
pdfStamper.close();
//将要生成的目标PDF文件名称
OutputStream fileOutputStream = new FileOutputStream(fileName);
fileOutputStream.write(byteArrayOutputStream.toByteArray());
fileOutputStream.flush();
fileOutputStream.close();
byteArrayOutputStream.close();
}
/**
* 解决utf8字符串中有隐含字符问题
* @param str
* @return
*/
public static String deleteUtf8Bom(String str) {
byte[] utf8BomBytes = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
byte[] bytes = str.getBytes();
if (bytes[0] == utf8BomBytes[0]
&& bytes[1] == utf8BomBytes[1]
&& bytes[2] == utf8BomBytes[2]) {
return new String(bytes, 3, bytes.length - 3);
}
return str;
}
}