生成pdf文件的方法有很多,网上也有很多的介绍,本文主要主要是讲生成pdf乱码的问题,而且还十分诡异,具体生成pdf的步骤同学们可以自己百度,也可以参考如下链接:
https://www.cnblogs.com/LUA123/p/5108007.html
最开始我也是参考这篇文章来制作pdf的,但是坑爹的步骤开始了,一开始就是中文不显示的问题,然后我就想到了是不是字体什么的不支持的问题,然后就找到了设置字体的方法,导入jar包itext-asian,添加如下代码:
AcroFields form = stamper.getAcroFields();
// 设置字体,防止中文乱码
// 引用jar包itext-asian
BasFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(1);
fontList.add(bf);
form.setSubstitutionFonts(fontList);
然后运行代码,生成pdf,效果还不错,可以显示中文,然后就调调格式,以为即将结束的时候,坑爹的时候开始了,在用户的机子上打开,中文全是乱码
what are you 弄啥呢!!!
然后我开始怀疑是不是自己编辑器设置的编码集什么的问题,开始各种查找,都确认没问题呢,然后又是网上一通搜索“itextpdf生成pdf中文乱码”,都是这种写法,没毛病啊。
在没有办法了的情况下,我把客户那里生成的pdf复制到了我自己电脑上,用自己的pdf阅读器,word以google浏览器打开都是正常的。顿时我心中一万头草泥马崩腾而过。
我再次转战到客户的机子上,也用word和google打开了那一份pdf文件,咦……是中文呀。。。难道是我刚才错觉?再次用pdf阅读器打开,现实再一次打击到了我,中文依旧乱码,我顿时冒火了,这什么破阅读器,啥烂玩意儿,是不是没有升级到最新版,我立马找到了阅读器顶上的帮助,点进去,然后再到官网查看对比,虽然不是最新版,但是也不算就,去年底出来的,我心中那一顿火,立马把这个破阅读器和作者骂了千百回,从此我深深的记住了这个阅读器的名字:Apabi Reader
骂归骂,问题还是要解决,而且客户那边基本上都安装的是这个破烂玩意儿,于是乎,我又开始了无尽头的查找,终于在快要绝望的时候,无意间发现了一个利用本地字体来写pdf的文章,自己脑中也产生了一个想法,是不是itext-asian 中的字体他不支持,于是我讲windows自带的字体复制了一个出来放在项目中,将上面的代码更改如下:
AcroFields form = stamper.getAcroFields();
// 设置字体,防止中文乱码
// // 引用jar包itext-asian
// BasFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
// 在个别pdf中引用的字体在个别pdf阅读器中会出现乱码,如:Apabi Reader,引用字体文件(一定记得字体后加“,1”)
BaseFont bf = BaseFont.createFont("D:/sumsun.ttc,1",BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(1);
fontList.add(bf);
form.setSubstitutionFonts(fontList);
依然没解决,那应该是模板设置的字体有问题,然后,我就讲模板中所有的字体也都设置成“宋体”,再试,终于搞定,真的是风雨后见彩虹啊。。。
最后,附上所有源码,仅供参考:
package com.sqxxcx.customer.ssjjfx.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
public class PDFUtil {
private static String PDF_TEMPLATE_PATH = null;
private static PDFUtil pdfUtil = null;
public static PDFUtil getInstance() {
if (null == pdfUtil) {
pdfUtil = new PDFUtil();
}
return pdfUtil;
}
private void getPdfTemplate() {
if (null == PDF_TEMPLATE_PATH) {
// pdf模板路径
PDF_TEMPLATE_PATH = this.getClass().getClassLoader().getResource("security/last_template.pdf").getPath();
}
}
/**
*
* @param pdfValues 生产pdf所需要的数据
* @param pdfPath 生成的新文件路径
* @param sealPath 印章路径
* @throws IOException
* @throws DocumentException
*/
public void generateFile(Map<String, String> pdfValues, String pdfPath, String sealPath)
throws IOException, DocumentException {
getPdfTemplate();
PdfReader reader = null;
FileOutputStream out = null;
ByteArrayOutputStream bos = null;
PdfStamper stamper = null;
System.out.println(new File(PDF_TEMPLATE_PATH).getAbsoluteFile());
reader = new PdfReader(PDF_TEMPLATE_PATH);// 读取pdf模板
bos = new ByteArrayOutputStream();
stamper = new PdfStamper(reader, bos);
AcroFields acroFields = stamper.getAcroFields();
/* 使用中文字体 */
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
// BaseFont bf = BaseFont.createFont(
// this.getClass().getClassLoader().getResource("security/simsun.ttc").getPath() + ",1",
// BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(1);
fontList.add(bf);
acroFields.setSubstitutionFonts(fontList);
// Map<String, String> pdfValues = getPdfValues();
Set<String> keySet = pdfValues.keySet();
for (String key : keySet) {
String value = pdfValues.get(key);
acroFields.setField(key, value);
}
// 插入图片
addImage(stamper, acroFields, sealPath);
stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true
stamper.close();
Document doc = new Document();
out = new FileOutputStream(pdfPath);// 输出流
PdfCopy copy = new PdfCopy(doc, out);
doc.open();
PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
copy.addPage(importPage);
doc.close();
}
private void addImage(PdfStamper stamper, AcroFields acroFields, String sealPath)
throws BadElementException, MalformedURLException, IOException, DocumentException {
int pageNo = acroFields.getFieldPositions("zgswjggz").get(0).page;
Rectangle signRect = acroFields.getFieldPositions("zgswjggz").get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
// 读图片
Image image = Image.getInstance(sealPath);
// 获取操作的页面
PdfContentByte pdfContentByte = stamper.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 添加图片
image.setAbsolutePosition(x, y);
pdfContentByte.addImage(image);
}
}