Opentaps(OFBiz)下fop(生成PDF)中文乱码解决方案
皇甫浩壤
2023-12-01
(本文来自[url]http://www.yuendong.com.cn/info.asp?id=157[/url])
在使用Opentaps(OFBiz)中,发现所有生成的PDF文件中,所有中文都不能显示,以”#“表示。自己在网上查了一些资料,主要参考http://leomne.iteye.com/blog/684421和http://www.vtimes.net/blog/article/add-chinese-font-for-fop-summary.html这篇文章,自己总结一下。
在ofbiz中,下面以一个例子来说明生成pdf的过程是:
1、访问https://localhost:8443/warehouse/control/shipGroups.pdf?orderId=DEMO_B2C_UK02&shipGroupSeqId=00001
2、再到warehouse 模块controller.xml找到对应的screen为,就是要显示的地方。在controller.xml的上部有如下配置:
说明这个渲染的时候会利用ScreenFopViewHandler。
3、在ScreenFopViewHandler.java中,先把reportTemplate.fo.ftl渲染成xml
// render and obtain the XSL-FO
Writer writer = new StringWriter();
FopFactory fopFactory = ApacheFopFactory.instance();
ScreenRenderer screens = new ScreenRenderer(writer, null, htmlScreenRenderer);
screens.populateContextForRequest(request, response, servletContext);
// this is the object used to render forms from their definitions
screens.getContext().put("formStringRenderer", new FoFormRenderer(request, response));
screens.render(page);
然后由apache的FOP(Formatting Objects Processor)对xml渲染,生成pdf文件,并放回到response中输出:
ByteArrayOutputStream out = new ByteArrayOutputStream();
TransformerFactory transFactory = TransformerFactory.newInstance();
try {
Fop fop = fopFactory.newFop(contentType, out);
Transformer transformer = transFactory.newTransformer();
// set the input source (XSL-FO) and generate the output stream of contentType
Reader reader = new StringReader(writer.toString());
Source src = new StreamSource(reader);
// Get handler that is used in the generation process
Result res = new SAXResult(fop.getDefaultHandler());
// Transform the FOP XML source
transformer.transform(src, res);
// We don't want to cache the images that get loaded by the FOP engine
fopFactory.getImageFactory().clearCaches();
// set the content type and length
response.setContentType(contentType);
response.setContentLength(out.size());
// write to the browser
out.writeTo(response.getOutputStream());
response.getOutputStream().flush();
由于Apache FOP中不支持任务中文字体,所以我们要把支持中文字体手动加入进来,下面分三步进行使pdf中的中文正常显示:
1、 用FOP生成黑体字体配置文件simhei.xml。这里的作用是字体映射成xml文件使得fop能够识别它们,所以要想Opentaps(OFBiz)能够使用它,你必须得你的操作系统支持这个字体。如果你操作系统不支持这个字体,下面的步骤很难实现。这个也是比较容易混淆和迷茫的地方。我们分成几个小步骤。
① 首先生成simhei.xml文件。生成这个方法比较简单的方法是把fop的依赖包先放进jre的lib的扩展包ext里面,我的路径是C:\Program Files\Java\jre6\lib\ext,后在控制台(cmd)直接执行java org.apache.fop.fonts.apps.TTFReader C:\Windows\Fonts\simhei.ttf D:\simhei.xml.(操作完了记得把他们删掉,因为放在这里了别的项目也会使用,很可能导致冲突,我自己就是,开始没有删除导致后来opentaps启动不了,因为包冲突了。)你会发现在d盘出现了simhei.xml的文件。
② 把C:\Windows\Fonts\simhei.ttf和simhei.xml一起考入到opentaps里面,路径为:${OPENTAPS_HOME}/opentaps/opentaps-common/lib/DejaVu下面。
2、修改ofbiz中fop的配置文件fop.xconf,路径为:${OPENTAPS_HOME}/framework/webapp/config/fop.xconf
添加字体:simhei
3、修改*.fo.ftl模板文件,把font-family改为simhei
重启看到pdf能正常显示中文了!