jarsperreport6.3解决pdf在linux无法打印汉字的问题。

来源:互联网 发布:苹果网络锁是什么意思 编辑:程序博客网 时间:2024/06/05 15:49

jarsperreport6.3的官方文档中写道。

http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/util/JRFontNotFoundException.html

This is why we encourage our users to package up TTF files as font extensions, using built JasperReports font extension support, and thus make sure the report template is deployed together with the fonts it needs to render properly. Fonts used inside a report template should be considered as indispensable resources, just like image files and resource bundles. Just as a report would not display properly if some required logo image is missing, the same way the report would not display properly if some required font is missing as well. And just as the logo image is shipped with the report template, the same way font files should be shipped as well.

这段话的意识是说:推荐大家使用 把字体包放到工程项目里面,字体文件随着项目走,就不会受到JVM平台的影响。


可是使用ireport或者jarsperreport把extension导出来。然后部署到项目里面

大致的结构如下图所示:


fonts.xml内容

    <?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
<fontFamily name="CCSSimsun">
<normal>
<ttf><![CDATA[fonts/CCSSimsun/simsun.ttf]]></ttf>
<pdf><![CDATA[fonts/CCSSimsun/simsun.ttf]]></pdf>
</normal>
<bold>
<ttf><![CDATA[fonts/CCSSimsun/simsunbd.ttf]]></ttf>
<pdf><![CDATA[fonts/CCSSimsun/simsunbd.ttf]]></pdf>
</bold>
<pdfFontName><![CDATA[CCSSimsun]]></pdfFontName>
<pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
<exportFonts/>
<!--
<locales>
<locale><![CDATA[zh_CN]]></locale>
</locales>
--> 
</fontFamily>
</fontFamilies>


fonts.xml 中的locale节点一定要注释掉,如果不注释掉,jarsperreport将不会用你放到项目的字体文件,而是直接从JVM平台查找字体文件。

这个地方是个坑,因为导出来的xml本来就带有locale节点。

jasperreports_extension.properties的内容为:

net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.CCSSimsun=fonts/fonts.xml

jasperreports.properties的内容为:

net.sf.jasperreports.export.pdf.fontdir.jasper=fonts/CCSSimsun


打印PDF的方法为:

public void printPdf() throws Exception {

ServletContext context = request.getSession().getServletContext();
response.setContentType("application/pdf");
response.setCharacterEncoding("UTF-8");


try
{
String fontFilePath =context.getRealPath("/WEB-INF/classes")+"/";
String subReportPath=context.getRealPath("/WEB-INF/classes/print")+"/";


//EnvironmentFactory.getEnvironment().

File reportFile = new File(context.getRealPath("/WEB-INF/classes/print/"+jasperFileName+".jasper"));
logger.debug("reportFile path......"+reportFile.getAbsolutePath());
if (!reportFile.exists())
throw new Exception("未找到文件名为:"+jasperFileName+"的打印模板");

//JasperDesign design = JRXmlLoader.load(reportFile);
//JasperReport jasperReport = JasperCompileManager.compileReport(design);

JasperReportsContext jrcontext=new SimpleJasperReportsContext();
JasperReport jasperReport = (JasperReport)JRLoader.loadObjectFromFile(reportFile.getPath());
jasperReport.setJasperReportsContext(jrcontext);
final Font awtFont=FontUtil.getInstance(jrcontext).getAwtFontFromBundles("CCSSimsun", Font.PLAIN, 20.0f, null, false);

//解决barcode下面的数字打印不出来的问题,保证barbecue字体和jarsperrepor字体一致
Environment env=new Environment() {

public final Font DEFAULT_FONT = awtFont;

//linux下没有安装图形化界面,但是本机是正常的,所以此处执行时会抛出异常,获取不到每英寸的像素点的个数。
public int getResolution() {
//Toolkit.getDefaultToolkit().getScreenResolution();
return 360;
}

   public Font getDefaultFont() {
       return DEFAULT_FONT;
   }
};
EnvironmentFactory.setDefaultEnvironment(env);

Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("SUBREPORT_DIR", subReportPath);

JRBeanCollectionDataSource beanSource=new JRBeanCollectionDataSource(printBean);

JasperPrint jasperPrint = 
JasperFillManager.fillReport(
jasperReport, 
parameters,
beanSource
);

//JRStyle style = new JRBaseStyle();  
//style.setPdfEmbedded(true);
//style.setPdfFontName("simsun");
//style.setPdfEncoding("Identity-H");
//jasperPrint.setDefaultStyle(style);

JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(response.getOutputStream()));
exporter.exportReport();

logger.debug("report pdf generate over....");
}catch(Exception e){
logger.error("print report pdf error:",e);
throw e;
}
}

0 0
原创粉丝点击