现象
itextpdf 打印时中文字体显示不出来,莫名其妙的消失不见了。具体现象如下图所示。
真正的理想情况如下图。
解决方案
本质原因是因为字体没有加载到,我们直接启动时加载字体,然后在打印时指定字体就好。当然,机器上也要下载字体。
(说明:别听其他地方说啥引入itext-asian就好,没用的,一定要手动加载字体!!)
机器层面
在dockerfile中添加如下部分。
mkdir -p /etc/fonts && \
wget -O /etc/fonts/pingfang.ttf http://taobaodianying.oss-cn-zhangjiakou.aliyuncs.com/cinema-card/font/PingFang-Medium.ttf
代码层面
每个人的代码都不一样,我给个示例大家参考下就好。
代码示例
加载字体相关代码。
static {
try {
if (DevelopUtil.isLocal()) {
BaseFont baseFont = BaseFont.createFont("pingfang.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
TEXT_FONT = new Font(baseFont, 10, Font.NORMAL);
} else {
String dirPath = "/etc/fonts";
BaseFont baseFont = BaseFont.createFont(dirPath + "/pingfang.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
TEXT_FONT = new Font(baseFont, 10, Font.NORMAL);
}
} catch (DocumentException | IOException e) {
log.error("字体加载错误", e);
}
}
打印时的部分代码。
Document doc = new Document(PageSize.A4, 20, 20, 20, 20);
try {
PdfWriter.getInstance(doc, new FileOutputStream(mOutputPdfFileName));
doc.open();
doc.newPage();
Image png1 = Image.getInstance(imageUrl);
doc.add(png1);
doc.add(new Paragraph(" " + f1Id
+ " " + colorInfo, TEXT_FONT));
doc.add(new Paragraph(" " + sellerId
+ " " + sellerItemCode, TEXT_FONT));
doc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
File mOutputPdfFile = new File(mOutputPdfFileName);
if (!mOutputPdfFile.exists()) {
mOutputPdfFile.deleteOnExit();
return null;
}
打印时的代码要注意的是,在Paragraph创建时要指定字体。(缩进这里用的空格代替,代码很丑陋,有知道怎么写的优雅的朋友记得评论或私聊我)
补充说明
在加载字体的时候需要区分本地测试和线上路径的不同。我这里用DevelopUtil来判断是否本地,如果是本地的话直接从工程根目录找字体,不是本地的话到指定目录去找。附带判断是否本地idea启动的代码,如下所示。
/**
* 判断当前是否是本地idea启动
* @return
*/
public static boolean isLocal(){
try {
Class.forName("com.intellij.rt.execution.application.AppMainV2");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}