itextpdf生成pdf中文乱码 (乱码中挣扎的自述)

生成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);
	}
}

 

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值