转载请注明出处 https://www.cnblogs.com/majianming/p/9537173.html
项目中需要对订单生成pdf文件,在不断的尝试之后,终于生成了比较满意的pdf文档。
简单介绍一下背景:项目是一个erp项目,docker容器化CentOS 7运行环境,应用打包方式jar,使用itext生成pdf

我们从后面的三个背景来分析

  1. 首先是使用itext库,需要明确的是itext是默认不支持中文显示的,这个问题很容易找到的方法是添加itext-asin库,一个解决中日韩文字问题的拓展,而在这个拓展自然也是需要另外添加中文字体支持的,所以我们为了支持中文,在itext的基础上需要itext-asin库和字体文件。
  2. 第二个背景,也就是jar打包方式,许多博客在介绍这一段时,会把字体文件添加到项目文件下,这样本地开发是没有问题的,但是一旦部署到了linux(CentOS)环境下,就会有中文字无法显示的问题(这时候如果你将应用的jar包在windows环境下跑,一般是可以正常显示的,为什么?等会看看第三个背景你就会明白了),这是因为在itext中,并不是用文件流(fileinputstream)的形式去读取字体,自然无法读取到jar包中的文件,那么我们换一个思路,把字体文件移动到项目外的一个路径下,然后指定itext去读取这个路径。
  3. 第三个背景CentOS,一般的服务器环境自然不会带中文字体的,那么我们需要将添加字体到哪里?随便加一个地方?且慢,我们先看一个地方
    com.itextpdf.text.FontFactoryImp#registerDirectories()下,我们发现了这样一段代码
String windir = System.getenv("windir");
String fileseparator = System.getProperty("file.separator");
if (windir != null && fileSeparator != null) {
fontResolver.addFontDirectory(windir + fileseparator + "fonts", BaseFont.NOT_EMBEDDED);
}
fontResolver.addFontDirectory("/usr/share/X11/fonts", BaseFont.EMBEDDED);
fontResolver.addFontDirectory("/usr/X/lib/X11/fonts", BaseFont.EMBEDDED);
fontResolver.addFontDirectory("/usr/openwin/lib/X11/fonts", BaseFont.EMBEDDED);
fontResolver.addFontDirectory("/usr/share/fonts", BaseFont.EMBEDDED);
fontResolver.addFontDirectory("/usr/X11R6/lib/X11/fonts", BaseFont.EMBEDDED);
fontResolver.addFontDirectory("/Library/Fonts", BaseFont.EMBEDDED);
fontResolver.addFontDirectory("/System/Library/Fonts", BaseFont.EMBEDDED);

也就是说,itext已经把背景分析2中的指定字体路径的事情做了,只是我们还没有字体在对应的路径上
然后我们再看看其中的这个代码

String windir = System.getenv("windir");
String fileseparator = System.getProperty("file.separator");
if (windir != null && fileSeparator != null) {
fontResolver.addFontDirectory(windir + fileseparator + "fonts", BaseFont.NOT_EMBEDDED);
}

windir? 比较熟悉windows下变量的人可以知道,这个是获取windows系统根路径的一个环境变量,我是win 10的电脑,获取的就是C:\Windows。
我们打开C:\Windows\fonts路径,会发现都是相关字体文件,也就是解释了为什么在linux中文无法显示的jar包在Windows下可以正常显示了——并不是在windows下可以读取到jar包的字体文件,而是在windows下可以读取到系统中的字体文件。
因为这个原因,自然可以显示中文字体;所以,如果要显示任何自定义的字体,在windows下,我们可以将可以添加到C:\Windows\fonts下;在liunx环境下,添加到对应的路径下即可。我们理论上可以使用任何一个系统中已经定义的字体。在这里,我们选择了/usr/share/fonts这个路径,当然这个路径在CentOS中是不存在的,所以要手动创建,然后将需要的中文字体复制进去

因为公司的环境是k8s的docker容器,为了平时的docker容器部署方便,我们依然把字体文件放在工程下(与dockerfile同一级),然后使用docker的命令将字体复制到指定路径下

COPY ./fonts/ /usr/share/fonts/

参考

docker cp命令 | Docker Documentation

转载请注明出处 https://www.cnblogs.com/majianming/p/9537173.html