Confluence导出中文pdf分析(&FOP中文字体支持分析)

现象

默认安装的Confluence在使用导出pdf时,如果页面包含有非英文字符,例如中文,日文,韩文等,相应位置就会出现#字符.

分析

通过查看Confluence的相关文件,可以了解到Confluence是使用FOP(http://xmlgraphics.apache.org/fop/)来输出pdf文件的,使用的是FOP Version 0.20.5.

FOP 0.20.5功能相对还是比较弱,例如

  1.不支持多种字体的组合,也就是不支持font-family="sans-serif,宋体"这种方式,
   结果就是每段都要指定,否则就只能用一种了,对于confluence来说就很不好了...
   
  2.不支持程序处理斜体,黑体,这样就要求字体支持黑体,斜体才能实现黑体斜体的效果.
    结果就是中文字体都没有黑体,斜体,无法直接实现中文的黑体,斜体了
   
   
   
我们再看看Confluence的导出功能,Confluence的导出功能是在WEB-INF\classes\importExportSubsystemContext.xml里面定义的,

<bean id="pdfExporter" class="com.atlassian.confluence.importexport.impl.PdfExporter" singleton="false">

  
通过查看PdfExporter这个文件,我们可以了解,Confluence是把字体配置信息写在了类里面,外部无法直接配置.Confluence的字体配置是使用了Verdana,Verdana字体有四种方式:普通,黑体,斜体,黑体+斜体,这是一种英文的字体,支持英文是没问题的,但是无法支持中文.

通过查看程序,我们还可以知道Confluence是通过固定的fo模板导出pdf的,模板分别为:WEB-INF\classes\com\atlassian\confluence\pages\Page.pdfexport.vm,Page-hierarchy.pdfexport.vm,Space.pdfexport.vm,通过查看这些模板文件,我们可以看到:

 <fo:flow flow-name="xsl-region-body" font-family="Verdana" font-size="11pt" text-align="justify">

 
类似的语句,也就是说Confluence默认使用这个字体输出pdf文件.

不完美的解决方案

因为Verdana 不支持中文,所以我们必须修改这些处理,下面的解决的方案虽然不是完美的,但是也部分解决了导出pdf的问题.

方案缺点:
 1.不支持多语言,例如对日文,韩文等的支持:期待FOP支持字体组合,或者Confluence支持字体配置
 2.使用固定字体,例如宋体:期望Confluence支持字体配置
 3.不能支持黑体,斜体(变通方法:通过使用黑体代替宋体的黑体,可以支持黑体) :期望有中文字体支持黑体,斜体,或者FOP内部提供支持
 4.英文的黑体,斜体也和中文一样了:bold使用黑体,斜体不支持了.
 
方案步骤:

1.下载FOP 0.20.5,解压,阅读文档
2.使用FOP的ttfreader生成字体的xml文件,例如微软提供的宋体,黑体,或者你喜欢的其他字体,以下均已宋体和黑体为例
 
  注意:FOP自带的Xalan 2.4.1版本在windows下运行生成xml文件时有点问题,换为confluence自带的2.7.0问题消失.
 
  把fop.bat复制为ttfreader.bat,修改文件最后一行为:

java -cp "%LOCALCLASSPATH%" org.apache.fop.fonts.apps.TTFReader %1 %2 %3 %4 %5 %6 %7 %8 

 并且把xalan的jar改为2.7.0的jar.
 
  或者直接使用命令行方式也可,自己拼接吧.
 
  ttfreader -ttcname "SimSun" C:\WINNT\Fonts\simsun.ttc simsun.xml        
  ttfreader C:\WINNT\Fonts\simhei.ttf simhei.xml                                      

 
生成了2个字体的文件,把xml文件和2个字体文件复制到confluence的WEB-INF\classes\fonts目录下.

3.修改PdfExporter
 为了简单,我们使用继承的方法生成一个新的类,例如:

package com.jscud.confluence.importexport.impl;


import java.util.ArrayList;
import java.util.List;
import org.apache.fop.configuration.*;

import com.atlassian.confluence.importexport.impl.PdfExporter;


public class ScudPdfExporter extends PdfExporter
{

    public ScudPdfExporter()
    {
        List fonts = new ArrayList();
        CustomFontInfo font_info = new CustomFontInfo(null, "fonts/verdana.xml", true, createFontTriplets(
                        "Verdana", "normal", "normal"), "fonts/verdana.ttf");
        fonts.add(font_info);
        font_info = new CustomFontInfo(null, "fonts/verdanab.xml", true, createFontTriplets("Verdana",
                        "bold", "normal"), "fonts/verdanab.ttf");
        fonts.add(font_info);
        font_info = new CustomFontInfo(null, "fonts/verdanai.xml", true, createFontTriplets("Verdana",
                        "normal", "italic"), "fonts/verdanai.ttf");
        fonts.add(font_info);
        font_info = new CustomFontInfo(null, "fonts/verdanaz.xml", true, createFontTriplets("Verdana",
                        "bold", "italic"), "fonts/verdanaz.ttf");
        fonts.add(font_info);
       

        font_info = new CustomFontInfo(null, "fonts/simsun.xml", true, createFontTriplets("SimSun","normal","normal"),
                        "fonts/simsun.ttc");
        fonts.add(font_info);
       
        font_info = new CustomFontInfo(null, "fonts/simhei.xml", true, createFontTriplets("SimSun",
                        "bold", "normal"), "fonts/simhei.ttf");
        fonts.add(font_info);

        font_info = new CustomFontInfo(null, "fonts/simsun.xml", true, createFontTriplets("SimSun","normal","italic"),
        "fonts/simsun.ttc");
       
        fonts.add(font_info);
       
        font_info = new CustomFontInfo(null, "fonts/simhei.xml", true, createFontTriplets("SimSun",
                        "bold", "italic"), "fonts/simhei.ttf");
        fonts.add(font_info);

        Configuration.put("fonts", fonts, 0);
       
       
    }

    private List createFontTriplets(String name, String weight, String style)
    {
        List triplets = new ArrayList();
        triplets.add(new FontTriplet(name, weight, style));
        return triplets;
    }
   
    /**
     * create font Triplets.
     *
     * main for chinese font ,not had bold,italic support.
     *
     * @param name font name
     * @return font triplets
     */
    protected List createScudFontTriplets(String name)
    {
        List triplets = new ArrayList();
        triplets.add(new FontTriplet(name, "normal","normal"));
        triplets.add(new FontTriplet(name, "bold","normal"));
        triplets.add(new FontTriplet(name, "normal","italic"));
        triplets.add(new FontTriplet(name, "bold","italic"));
        return triplets;
    }

}



 

编译此类,并把类复制到Confluence的对应目录下.
 

然后修改前面提到的importExportSubsystemContext.xml,修改对应的一行为

<bean id="pdfExporter" class="com.jscud.confluence.importexport.impl.ScudPdfExporter" singleton="false">

(再次体会到依赖注射的好处啊)


4.修改前面提到的模板文件的字体设置

<fo:flow flow-name="xsl-region-body" font-family="Verdana" font-size="11pt" text-align="justify">

改为

<fo:flow flow-name="xsl-region-body" font-family="SimSun" font-size="11pt" text-align="justify">

 

注意:模板文件中还有一些地方的字体设置要改,自己挖掘吧,不改的话,可能会出现###哦

 

5.修正生成pdf时的中文换行问题

  我们还需要修改模板文件里面的:


  <fo:page-sequence master-reference="all-pages">
  改为
  <fo:page-sequence master-reference="all-pages" language="zh">
 
  这样中文文字换行就没问题了
 
 
6.重启web application
  试试导出pdf,看到中文了吧
 
 

 
说明


  1.本人第一次接触FOP,感觉是个好东西,不过非常不了解,也许相对上面提到的方法还有更好的方法来解决,如果你知道,请不吝指教.
  2.Confluence的国际化还有很长的路要走,不过我也没怎么研究过...没源码就是不好研究

 

 


 
创造共用协议:署名,非商业,保持一致   除经特别注明外,本文章版权归JScud Develop团队或其作者所有.
署名,非商业用途,保持一致.   scud(飞云小侠)   JScud Develop

posted on 2006-01-10 14:22 Scud(飞云小侠) 阅读(5659) 评论(4)  编辑  收藏 所属分类: 其他

评论

# re: Confluence导出中文pdf分析(&FOP中文字体支持分析) 2006-01-10 15:57 oztime

期待继续深入研究!  回复  更多评论   

# re: Confluence导出中文pdf分析(&FOP中文字体支持分析) 2006-01-11 16:27 scud(飞云小侠)

研究啥?  回复  更多评论   

# re: Confluence导出中文pdf分析(&FOP中文字体支持分析) 2007-01-17 19:53 BeanSoft

支持!  回复  更多评论   

# re: Confluence导出中文pdf分析(&FOP中文字体支持分析) 2011-05-09 09:39 sysme

为什么你说的配置文件我没找到?难道是版本的问题。我用的是3.5版。期待楼主回复。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2006年1月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

公告

文章发布许可
创造共用协议:署名,非商业,保持一致

我的邮件
cnscud # gmail


常用链接

留言簿(15)

随笔分类(113)

随笔档案(103)

相册

友情链接

技术网站

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜