解決jasperreports中自定義字型在linux沒有生效和不加粗問題
我的jasper的maven配置
<dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>6.3.0</version> </dependency> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports-fonts</artifactId> <version>5.6.1</version> </dependency>
1:我們開發報表有些時候官方預設的字型包不能滿足我們的需要,所以我們開始自定義字型,於是在網上查了很多資料,按照網上的方式自定義的字型檔案放到jasperreports-fonts-5.6.1.jar的net\sf\jasperreports\fonts\dejavu目錄下,字型檔案要求必須ttf格式,然後在net\sf\jasperreports\fonts\fonts.xml檔案中增加字型配置,我的配置如下:
<fontFamily name="DejaVu 宋體"> <normal>net/sf/jasperreports/fonts/dejavu/simsun.ttf</normal> <bold>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</bold> <italic>net/sf/jasperreports/fonts/dejavu/simsun.ttf</italic> <boldItalic>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</boldItalic> <pdfEncoding>Identity-H</pdfEncoding> <pdfEmbedded>true</pdfEmbedded> <exportFonts> <export key="net.sf.jasperreports.html">'宋體','simsun'</export> <export key="net.sf.jasperreports.xhtml">'宋體','simsunbd'</export> </exportFonts> </fontFamily> <fontFamily name="DejaVu 仿宋_GB2312"> <normal>net/sf/jasperreports/fonts/dejavu/simsun.ttf</normal> <bold>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</bold> <italic>net/sf/jasperreports/fonts/dejavu/simsun.ttf</italic> <boldItalic>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</boldItalic> <pdfEncoding>Identity-H</pdfEncoding> <pdfEmbedded>true</pdfEmbedded> <exportFonts> <export key="net.sf.jasperreports.html">'宋體','simsun'</export> <export key="net.sf.jasperreports.xhtml">'宋體','simsunbd'</export> </exportFonts> </fontFamily>
2:將修改後的jasperreports-fonts-5.6.1.jar包檔案放到專案的lib下,最後到linux環境測試生成PDF的效果,有沒有使用到自己定義的宋體字型,但是現實總是如此,結果給了我一個很響亮的大嘴巴子,根本沒有任何效果,於是我百思不得其解,又開始了漫長的百度和google里程,講道理啥結果也沒找過,但是還是有些文章給了我一定的啟發,於是我在想既然配置了字型,那麼jasperreports在生成時肯定會解析字型檔案,我一步一步去遠端debug除錯,最後定位到一段程式碼,跟蹤到FontUtil的getFontInfo方法,發現有個變數是用來儲存解析fonts.xml的字型配置的,程式碼如下:
public FontInfo getFontInfo(String name, Locale locale) {
FontInfo awtFamilyMatchFontInfo = null;
//families實際解析fonts.xml檔案的結果
List<FontFamily> families = this.jasperReportsContext.getExtensions(FontFamily.class);
Iterator itf = families.iterator();
while(true) {
FontFamily family;
do {
if(!itf.hasNext()) {
return awtFamilyMatchFontInfo;
}
family = (FontFamily)itf.next();
} while(locale != null && !family.supportsLocale(locale));
if(name.equals(family.getName())) {
return new FontInfo(family, (FontFace)null, 0);
}
FontFace face = family.getNormalFace();
if(face != null) {
if(name.equals(face.getName())) {
return new FontInfo(family, face, 0);
}
if(awtFamilyMatchFontInfo == null && name.equals(face.getFont().getFamily())) {
awtFamilyMatchFontInfo = new FontInfo(family, face, 0);
}
}
face = family.getBoldFace();
if(face != null) {
if(name.equals(face.getName())) {
return new FontInfo(family, face, 1);
}
if(awtFamilyMatchFontInfo == null && name.equals(face.getFont().getFamily())) {
awtFamilyMatchFontInfo = new FontInfo(family, face, 1);
}
}
face = family.getItalicFace();
if(face != null) {
if(name.equals(face.getName())) {
return new FontInfo(family, face, 2);
}
if(awtFamilyMatchFontInfo == null && name.equals(face.getFont().getFamily())) {
awtFamilyMatchFontInfo = new FontInfo(family, face, 2);
}
}
face = family.getBoldItalicFace();
if(face != null) {
if(name.equals(face.getName())) {
return new FontInfo(family, face, 3);
}
if(awtFamilyMatchFontInfo == null && name.equals(face.getFont().getFamily())) {
awtFamilyMatchFontInfo = new FontInfo(family, face, 3);
}
}
}
}
3:好了找到解析字型檔案的位置了,於是我就像到底有沒解析到配置的字型呢,於是debug看了下這個變數的值,結果是沒有的,只有三個值也就是fonts.xml預設的其中三個配置,配置如下:
<fontFamily name="SansSerif">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="Serif">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Serif', 'Times New Roman', Times, serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Serif', 'Times New Roman', Times, serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="Monospaced">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
</exportFonts>
</fontFamily>
但是我在windows環境看了下,解析的結果卻是fonts.xml所有的配置,結果完全不一致,這就很苦惱了,最後對比下解析的配置差異,發現linux環境只會解析我上面發的那三個配置資訊,而不會解析這樣的配置:
<fontFamily name="DejaVu 宋體">
<normal>net/sf/jasperreports/fonts/dejavu/simsun.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/simsun.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'宋體','simsun'</export>
<export key="net.sf.jasperreports.xhtml">'宋體','simsunbd'</export>
</exportFonts>
</fontFamily>
<fontFamily name="DejaVu 仿宋_GB2312">
<normal>net/sf/jasperreports/fonts/dejavu/simsun.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/simsun.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'宋體','simsun'</export>
<export key="net.sf.jasperreports.xhtml">'宋體','simsunbd'</export>
</exportFonts>
</fontFamily>
好了原因找到了,我就嘗試著去按照linux環境解析的配置xml格式配置了一下,最終配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
<fontFamily name="DejaVu Sans">
<normal>net/sf/jasperreports/fonts/dejavu/DejaVuSans.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/DejaVuSans-Bold.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/DejaVuSans-Oblique.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSans-BoldOblique.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
</exportFonts>
<!--
<locales>
<locale>en_US</locale>
<locale>de_DE</locale>
</locales>
-->
</fontFamily>
<fontFamily name="DejaVu Serif">
<normal>net/sf/jasperreports/fonts/dejavu/DejaVuSerif.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-Bold.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-Italic.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSerif-BoldItalic.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Serif', 'Times New Roman', Times, serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Serif', 'Times New Roman', Times, serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="DejaVu Sans Mono">
<normal>net/sf/jasperreports/fonts/dejavu/DejaVuSansMono.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/DejaVuSansMono-Bold.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/DejaVuSansMono-Oblique.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/DejaVuSansMono-BoldOblique.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
</exportFonts>
</fontFamily>
<!--
Mapping Java logical fonts, for the sake of HTML export only.
-->
<fontFamily name="SansSerif">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans', Arial, Helvetica, sans-serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="Serif">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Serif', 'Times New Roman', Times, serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Serif', 'Times New Roman', Times, serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="Monospaced">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu Sans Mono', 'Courier New', Courier, monospace</export>
</exportFonts>
</fontFamily>
<!--自定義字型配置開始-->
<fontFamily name="宋體">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu 宋體', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu 宋體', Arial, Helvetica, sans-serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="仿宋_GB2312">
<exportFonts>
<export key="net.sf.jasperreports.html">'DejaVu 仿宋_GB2312', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'DejaVu 仿宋_GB2312', Arial, Helvetica, sans-serif</export>
</exportFonts>
</fontFamily>
<fontFamily name="DejaVu 宋體">
<normal>net/sf/jasperreports/fonts/dejavu/simsun.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/simsun.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'宋體','simsun'</export>
<export key="net.sf.jasperreports.xhtml">'宋體','simsunbd'</export>
</exportFonts>
</fontFamily>
<fontFamily name="DejaVu 仿宋_GB2312">
<normal>net/sf/jasperreports/fonts/dejavu/simsun.ttf</normal>
<bold>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</bold>
<italic>net/sf/jasperreports/fonts/dejavu/simsun.ttf</italic>
<boldItalic>net/sf/jasperreports/fonts/dejavu/simsunbd.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'宋體','simsun'</export>
<export key="net.sf.jasperreports.xhtml">'宋體','simsunbd'</export>
</exportFonts>
</fontFamily>
<!--自定義字型配置結束-->
</fontFamilies>
4:最後將修改後的fonts.xml放到jasperreports-fonts-5.6.1.jar包中,丟到linux環境測試,結果很出乎意料字型解析到,加粗也沒問題了,至此解決了自定義字型加粗和字型未生效問題
5:最後宣告伺服器JDK最好使用jdk1.7.45~1.7.80版本不要使用linux自帶的JDK版本會存在一些問題,比如說不正常換行問題。