• 现象:在用 POI 志出 excel 的代码里,用到了 font,设置的字体是 Arial,在 windows 下测试没问题,但发布到 CentOS7,导出时报错。
  • 解决:在 CentOS 服务器上安装字体即可。

报错信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
java.lang.InternalError: java.lang.reflect.InvocationTargetException
at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:86) ~[?:?]
at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74) ~[?:?]
at java.awt.Font.getFont2D(Font.java:497) ~[?:?]
at java.awt.Font.canDisplayUpTo(Font.java:2246) ~[?:?]
at java.awt.font.TextLayout.singleFont(TextLayout.java:469) ~[?:?]
at java.awt.font.TextLayout.<init>(TextLayout.java:530) ~[?:?]
at org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(SheetUtil.java:273) ~[poi-4.1.0.jar:4.1.0]
at org.apache.poi.ss.util.SheetUtil.getColumnWidth(SheetUtil.java:248) ~[poi-4.1.0.jar:4.1.0]
at org.apache.poi.ss.util.SheetUtil.getColumnWidth(SheetUtil.java:233) ~[poi-4.1.0.jar:4.1.0]
at org.apache.poi.hssf.usermodel.HSSFSheet.autoSizeColumn(HSSFSheet.java:2215) ~[poi-4.1.0.jar:4.1.0]
at org.apache.poi.hssf.usermodel.HSSFSheet.autoSizeColumn(HSSFSheet.java:2197) ~[poi-4.1.0.jar:4.1.0]
at mis.api.common.excel.ExcelExportUtils.fillSheet(ExcelExportUtils.java:200) ~[mis-api-common-excel-1.0.0.jar:?]

报错的代码是:sheet.autoSizeColumn(i);

设置字体的方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private static HSSFCellStyle getStyleHeader(HSSFWorkbook wb) {
HSSFCellStyle style = wb.createCellStyle();
HSSFFont font = wb.createFont();
font.setFontName(HSSFFont.FONT_ARIAL);

//将字体颜色设为白色
font.setColor(IndexedColors.WHITE.index);
font.setFontHeight((short)220);
font.setBold(true);

style.setFont(font);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
//style.setWrapText(true);//设置自动换行

// 背景色
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(IndexedColors.GREY_80_PERCENT.index);
//style.setFillBackgroundColor(IndexedColors.YELLOW.index);

// 设置边框
setStyleBorder(style);

return style;
}

解决

  • 需要先安装 fontconfig

    1
    yum -y install fontconfig
  • 接着操作:

    1
    2
    3
    4
    mkdir -p /usr/share/fonts/arial
    cd /usr/share/fonts/arial
    # 上传字体文件,字体文件在 C:\Windows\Fonts\Arial 目录下,将所有文件上传至 /usr/share/fonts/arial
    chmod -R 755 /usr/share/fonts/arial # 能省吗?配置新服务器时留意。
  • 为刚加入的字体设置缓存使之有效

    1
    2
    3
    4
    cd /usr/share/font/arial
    mkfontscale
    mkfontdir
    fc-cache -fv
  • 重启 tomcat,再导出,就 ok 了。

    不重启,不知道是否也可以。配置新服务器时留意。

后记

曾尝试在一台不能上外网的服务器上离线安装相关依赖,但最终失败。

把相关依赖都下载了之后,最终的安装顺序如下:

1
2
3
4
rpm -ivh fontpackages-filesystem-1.44-8.el7.noarch.rpm
rpm -ivh dejavu-fonts-common-2.33-6.el7.noarch.rpm
rpm -ivh dejavu-sans-fonts-2.33-6.el7.noarch.rpm
rpm -ivh fontconfig-2.13.0-4.3.el7.x86_64.rpm

在执行 mkfontscale 命令时,提示无此命令

1
2
3
[root@localhost ~]# mkfontscale
mkfontscale: error while loading shared libraries: libfontenc.so.1: cannot open shared object file: No such file or directory
[root@localhost ~]#

用以下命令查找,发现找不到。

1
find / -name mkfontscale

于是在 yum 安装成功的电脑上把文件 copy 到相应位置,执行时,又报依赖问题,所以,离线安装失败。

1
2
[root@localhost ~]# mkfontscale
mkfontscale: error while loading shared libraries: libfontenc.so.1: cannot open shared object file: No such file or directory

离线安装包下载

rpm 包下载网站 -> rpmfind