转载请注明出处 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

在linux环境下使用itext生成pdf的更多相关文章

  1. Linux环境下动态链接库的生成和使用

    使用自己封装的so时遇到了点问题,本着简便原则决定写个demo看看,顺便记录下整个过程. 1)生成so所需的文件如下: print.h #ifndef __print_h__ #define __pr ...

  2. 在linux环境下使用icepdf或pdfbox将pdf转化成图片是乱码解决

    在linux环境下使用icepdf或pdfbox将pdf转化成图片是出现乱码,网上查发下是itextpdf生成pdf引用"STSong-Light"字体而linux环境下没有这个字 ...

  3. Linux环境下如何生成core文件

    Linux环境下进程发生异常而挂掉,通常很难查找原因,但是一般Linux内核给我们提供的核心文件,记录了进程在崩溃时候的信息.但是生成core文件需要设置开关,具体步骤如下: 1.查看生成core文件 ...

  4. 快速解决Ubuntu/linux 环境下QT生成没有可执行文件(application/x-executable)

    快速解决Ubuntu/linux 环境下QT生成没有可执行文件(application/x-executable)(转载)   问题描述 与windows环境下不同,linux选择debug构建时并不 ...

  5. linux 环境下运行STS时 出现must be available in order to run STS

    linux 环境下运行ECLIPSE时 出现 “ A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be avai ...

  6. Linux环境下段错误的产生原因及调试方法小结(转)

    最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且 项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的“段错误”(Segmentation F ...

  7. 【环境配置】Linux环境下下载、配置java环境、安装eclipse、建立eclipse快捷方式详解

    一.首先是下载Java JDK 到目前为止的最新版本为(jdk1.8.0_60),有两种方式进行下载: 1.使用shell来进行下载,可使用如下命令直接进行下载: wget --no-check-ce ...

  8. Linux环境下段错误的产生原因及调试方法小结

    转载自http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之 ...

  9. linux环境下安装sphinx中文支持分词搜索(coreseek+mmseg)

     linux环境下安装sphinx中文支持分词搜索(coreseek+mmseg) 2013-11-10 16:51:14 分类: 系统运维 为什么要写这篇文章? 答:通过常规的三大步(./confi ...

随机推荐

  1. 【JAVA】java中Future、FutureTask的使用

    如今的系统基本都是分布式的,各个系统各司其职的,不可能一个系统干了全部系统的事. 所以系统之间的交互就越来越多了.那么系统之间的交互仅仅有通过网络来交互了,而网络必定会存在延时的情况. 比方A系统的一 ...

  2. java 报错非法的前向引用

    今天在看<thinking in java>的时候,第四章提到了非法的前向引用,于是自己试了一下,书中的例子倒是一下就明白了,但是自己写的一个却怎么也不明白,于是上网问了一位前辈,终于明白 ...

  3. 连接虚拟机的SQLServer

    1.IP可以互相PING通 2.Telnet发现端口没有放开,防火墙新建入账规则开放端口 成功..

  4. mongo14-----group,aggregate,mapReduce

    group,aggregate,mapReduce 分组统计: group() 简单聚合: aggregate() 强大统计: mapReduce() db.collection.group(docu ...

  5. YTU 2555: 老大的烦恼

    2555: 老大的烦恼 时间限制: 1 Sec  内存限制: 128 MB 提交: 176  解决: 47 题目描述 万恶的小黑,布置了一道题给老大做:给你一个n位的数,现在要求 你随意删除m位后,任 ...

  6. HDU4704:Sum(欧拉降幂公式)

    Input 2 Output 2 Sample Input 2 由公式,ans=2^(N-1)%Mod=2^((N-1)%(Mod-1)+(Mod-1)) %Mod. 注意:降幂的之后再加一个Mod- ...

  7. BZOJ_2844_albus就是要第一个出场_线性基

    BZOJ_2844_albus就是要第一个出场_线性基 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S ...

  8. Combo Box (组合框)控件的使用方法

    Combo Box (组合框)控件很简单,可以节省空间.从用户角度来看,这个控件是由一个文本输入控件和一个下拉菜单组成的.用户可以从一个预先定义的列表里选择一个选项,同时也可以直接在文本框里面输入文本 ...

  9. socket实现进程间通信(转载)

    转自:http://blog.csdn.net/ast_224/article/details/3962221 使用socket实现进程间通信:(UNIX domain中面向连接通信) 使用套接字除了 ...

  10. bzoj 2216: [Poi2011]Lightning Conductor【决策单调性dp+分治】

    参考:https://blog.csdn.net/clove_unique/article/details/57405845 死活不过样例看了题解才发现要用double.... \[ a_j \leq ...