eXtremeComponent在中文环境下的使用

不知道大家是否使用过eXtremeComponent,最早知道eXtremeComponent是从www.open-open.com,去年就在用了,感觉明显比display-tag要好用多了。
它使用jstl,所以与webwork集成也很方便,不象display-tag那样需要把hibernate返回的collection复制一遍再访问。

具体的使用方法参考官方网站好了:
官方网站在这里:
http://www.extremecomponents.org/extremesite/welcome.jsp
最新的版本是1.0.1-M4-A14,可以到这里下载:
http://www.extremecomponents.org/extremesite/public/download/
或者直接下载:
http://www.extremecomponents.org/extremesite/public/download/extremecomponents-1.0.1-M4-A14.zip
但是这个snapshot版本没有依赖lib和资源文件等,推荐去这里下一个完整版本备用,目前最新的Production Release包是eXtremeComponents-1.0.1-M3-with-dependencies.zip:
https://sourceforge.net/project/showfiles.php?group_id=108168
最新版本的说明书在这里,说明书用的doc book格式,写的也很清楚:
http://www.extremecomponents.org/extremesite/public/download/eXtremeComponents.pdf
很多人都对他使用的doc book声称doc感兴趣,spring和hibernate都用doc book,可是一般看不到源文件。作者很慷慨将doc book的源文件也分享了,是学习是学习使用doc book的好东西:
http://www.extremecomponents.org/extremesite/public/download/generate-docs.zip

资源就贴到这里,这里要提及作者Jeff Johnston人非常热情,论坛上四处可见他的身影,给他发信他也是每信必会、有求必应,承蒙他多次帮助。而且论坛中大家多次提及中文问题,他也很重视。

转入正题:
我贴一下一个例子:
None.gif < ec:table 
None.gif
items ="ecoAttrs"  
None.gifaction
="/jgz/tjk/eco/listTjkAttByInfId.action"  
None.gifimagePath
="${pageContext.request.contextPath}/css/table/zh_CN/*.gif"  
None.gifcellpadding
="1"  
None.giftitle
="农村经济运行情况列表"  
None.giflocale
="zh_CN"  
None.gifrowsDisplayed
="30" >  
None.gif
< ec:export  view ="xls"  fileName ="jgz_zyjjzbwcqk.xls"  tooltip ="输出Excel文件" />  
None.gif
< ec:exportPdf  fileName ="jgz_zyjjzbwcqk.pdf"  tooltip ="输出PDF文件"  headerColor ="blue"  headerBackgroundColor ="red"  headerTitle ="密云县农村经济月份经济主要指标完成情况表" />  
None.gif
< ec:exportCsv  fileName ="jgz_zyjjzbwcqk.txt"  tooltip ="输出CSV文件"  delimiter ="|" />  
None.gif
< ec:row >  
None.gif
< ec:column  property ="ofTown.name"  title ="乡镇名称" />  
None.gif
< ec:column  property ="ncJihua"  title ="农村计划" />  
None.gif
< ec:column  property ="ncWancheng"  title ="农村完成" />  
None.gif
< ec:column  property ="ncQunian"  title ="农村去年" />  
None.gif
< ec:column  property ="zongShouRuWCJH"  title ="完成计划%" />  
None.gif
< ec:column  property ="zongShouRuTB"  title ="同比+/-%" />  
None.gif
</ ec:row >  
None.gif
</ ec:table >  

其中ecoAttrs是一个collection,放入pojo。action里面写你这个页面的访问方法(如我的页面是一个action,其他的如.do或者.jsp什么的都可以)。rowsDisplayed是默认显示条数,它可以自动实现分页。
下面的三个<ec:export>是导出三种格式用的,不用的话可以不写(写了需要在web.xml配置相应的filter)。
<ec:column>里面放属性,property指向pojo的相应属性,而title是表头显示的信息,这个标签需要用<ec:row>包起来(1.0.1 m4以后)(抱歉pojo比较丑,出自同事之手)。

这里放一套我做的中文图标:
http://tiny.51.net/extremecomponent/zh_CN.rar
还有我该写了一下css,更适合使用中文,将字体该为%大小,可以定义.eXtremeTable里面的font-size,即影响所有eXtremeTable里面的字体大小,也方便写js来动态修改大小:
http://tiny.51.net/extremecomponent/extremecomponents.css

贴一下我在web.xml里面的配置:
None.gif < filter >  
None.gif
< filter-name > eXtremeExport </ filter-name >  
None.gif
< filter-class >  
None.giforg.extremecomponents.table.filter.ExportFilter 
None.gif
</ filter-class >  
None.gif
</ filter >  
None.gif
None.gif
< filter-mapping >  
None.gif
< filter-name > eXtremeExport </ filter-name >  
None.gif
< url-pattern > /* </ url-pattern >  
None.gif
</ filter-mapping >  
None.gif
None.gif
< taglib >  
None.gif
< taglib-uri > /extremecomponents </ taglib-uri >  
None.gif
< taglib-location > /WEB-INF/tld/extremecomponents.tld </ taglib-location > <!--  别忘了把那个tld拷贝到相应目录去  -->  
None.gif
</ taglib >  

其实,那个filter只是在使用<ec:export>的时候才需要,不过这个功能还是很有用的。

export里面的excel和pdf默认不支持中文,需要手工修改源码,excel的比较简单:
修改org.extremecomponents.table.view.XlsView.java(我指的是1.0.1-M4-A14的相应代码)
102行:
None.gif HSSFCell hssfCell  =  hssfRow.createCell(cellnum); 
None.gifhssfCell.setEncoding(HSSFCell.ENCODING_UTF_16);(就是添加这一行) 
None.gif122行: 
None.gifHSSFCell cell 
=  row.createCell(cellnum); 
None.gifcell.setEncoding(HSSFCell.ENCODING_UTF_16);(就是添加这一行) 

这个在使用UTF-8时工作正常。如果其他Unicode环境可以尝试HSSFCell.ENCODING_COMPRESSED_UNICODE。

编译后将对应.class放到WEB-INF/classes相应目录就可以了。

pdf view的比较麻烦,还没尝试,解决方法参照这个帖子:
http://extremecomponents.org/forum/viewtopic.php?t=139&highlight=chinese+filter
http://www-128.ibm.com/developerworks/cn/xml/x-ospdf/index.html

还有一小点:
升级到1.0.1-M4-A14以后两个图片改名了,如果用1.0.1-M3的对应gif则需要该如下两个文件名(我修改的那个ZH-CN已经重命名过了):
searchArrow.gif -> filterArrow.gif
search.gif -> filter.gif

说的比较罗嗦,主要是想让和我一样的非常初级水平的朋友能够比较容易上手。其实eXtremeComponent的文档很不错,用那个上手其实更好,我仅抛砖引玉,各位大牛多多包涵。

下面是补充上的如何让PDF View支持中文,这个需要点耐心。
我是在WindowsXP里面(这个涉及到文件夹和所带的字体)。

1、解开fop-0.20.5.jar,启用cmd,并到它的目录中,执行:
None.gif java org.apache.fop.fonts.apps.TTFReader -ttcname "SimSun" C:\WINDOWS\Fonts\simsun.ttc simsun.xml 
None.gifjava org.apache.fop.fonts.apps.TTFReader -ttcname SimHei C:\WINDOWS\Fonts\simhei.ttf simhei.xml 

2、然后就会生成需要的两个字体描述文件:simsun.xml、simhei.xml
我们将我们生成的两个xml文件和它们对应的字体simsun.ttc和simhei.ttf存储到我们的Web项目的WEB-INF/fonts下面。
3、然后在我们的src目录(目的是要被部署到WEB-INF/classes目录,也有可能是/src/conf,看你的工程的设定)创建一个名为fop-pdf-userconfig.xml的文件,内容如下:
None.gif <? xml version="1.0" encoding="UTF-8" ?>  
None.gif
< configuration >  
None.gif
< fonts >  
None.gif  
< font  metrics-file ="@@@@@@@@@@fonts/simsun.xml"  
None.gif           embed-file
="@@@@@@@@@@fonts/simsun.ttc"  kerning ="yes" >  
None.gif            
< font-triplet  name ="SimSun"  style ="normal"  weight ="normal" />  
None.gif            
< font-triplet  name ="SimSun"  style ="normal"  weight ="bold" />  
None.gif            
< font-triplet  name ="SimSun"  style ="italic"  weight ="normal" />  
None.gif            
< font-triplet  name ="SimSun"  style ="italic"  weight ="bold" />  
None.gif  
</ font >  
None.gif  
< font  metrics-file ="@@@@@@@@@@fonts/simhei.xml"  
None.gif           embed-file
="@@@@@@@@@@fonts/simhei.ttf"  kerning ="yes" >  
None.gif            
< font-triplet  name ="SimHei"  style ="normal"  weight ="normal" />  
None.gif            
< font-triplet  name ="SimHei"  style ="normal"  weight ="bold" />  
None.gif            
< font-triplet  name ="SimHei"  style ="italic"  weight ="normal" />  
None.gif            
< font-triplet  name ="SimHei"  style ="italic"  weight ="bold" />  
None.gif  
</ font >  
None.gif
</ fonts >  
None.gif
</ configuration >

注意,其中有“@@@@@@@@@@”,因为我的实现方法很丑陋,我后面的代码中将“@@@@@@@@@@”替换为你部署后运行的路径,目的是字体文件等能够跟工程一同部署,减少固定字体等文件的麻烦。
4、对extremeComponent的代码,我又修改了两处:
其一,对于org.extremecomponents.table.view.PdfView修改:
将其中出现<fo:block的地方全部添加font-family=\"SimSun,SimHei\"。
然后double colwidth = 10 / columnCount;中的10修改为20,此处修改使中文字符不会堆积在一起。
我还将上面的sb.append(" page-width=\"11in\" ");修改为sb.append(" page-width=\"22in\" ");,这样对于中文比较宽大的报表可以显示完全,不过这个要自己把握。

其二,修改org.extremecomponents.table.filter.PdfViewResolver:
我在driver.run();前面增加如下一段代码:
ExpandedBlockStart.gif ContractedBlock.gif try   dot.gif
InBlock.gif            ClassLoader loader 
= Thread.currentThread().getContextClassLoader(); 
InBlock.gif            URL url 
= loader.getResource( 
InBlock.gif                    
"/org/extremecomponents/table/filter/PdfViewResolver.class"); //get the class's working folder 
InBlock.gif
            String classPathUrl = url.toExternalForm(); 
InBlock.gif            String fileRoot 
= classPathUrl.substring(0
InBlock.gif                    classPathUrl.lastIndexOf(
"WEB-INF")); 
InBlock.gif            fileRoot 
= (fileRoot.substring(6+ "WEB-INF/"); //cut the "file:/" prefix 
InBlock.gif

InBlock.gif            InputStream opis 
= loader.getResourceAsStream( 
InBlock.gif                    
"fop-pdf-userconfig.xml"); 
InBlock.gif            StringBuffer tempConfigurationStrBuf 
= new StringBuffer(); 
InBlock.gif
InBlock.gif            
byte[] buffer = new byte[4096]; 
InBlock.gif            
int len; 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
while ((len = opis.read(buffer)) != -1dot.gif
InBlock.gif                String s 
= new String(buffer, 0, len); 
InBlock.gif                tempConfigurationStrBuf.append(s); 
ExpandedSubBlockEnd.gif            }
 
InBlock.gif
InBlock.gif            String configurationStr 
= tempConfigurationStrBuf.toString(); 
InBlock.gif            configurationStr 
= configurationStr.replaceAll("@@@@@@@@@@"
InBlock.gif                    fileRoot); 
InBlock.gif
InBlock.gif            ByteArrayInputStream bais 
= new ByteArrayInputStream(configurationStr.getBytes()); 
InBlock.gif            org.apache.fop.apps.Options options 
= new org.apache.fop.apps.Options(); 
InBlock.gif            options.loadUserconfiguration(bais); 
ExpandedBlockStart.gifContractedBlock.gif        }
  catch  (FOPException fe)  dot.gif
InBlock.gif            fe.printStackTrace(); 
ExpandedBlockEnd.gif        }

大家可以抨击代码的丑陋,呵呵,不过还好it works。代码很丑陋,本来想咨询raimundo的,他正好忙,所以畸形了,如果朋友们有其它好方法可以一同改进。
不过要注意,我替换的/org/extremecomponents/table/filter/PdfViewResolver.class是放到WEB-INF/classes文件夹的,如果您将它替换到jar包里面,则上面内容还需要修改一下,我没有测试,但是估计也不麻烦的。

至此,最基本的解决Pdf export的方法就写好了。可是正好看到差沙已经早些放出了他的修改,明显比我这个优雅,但是他的修改无法将fonts里面的内容自动部署并检查目录,大家可以合并一下代码,相信会更好一点。回去好好学习差沙分享的代码,大家一同学习。

相关代码打包在这里:
http://tiny.51.net/extremecomponent/ec_pdf_chfix.rar

本解决方案参考了本贴:
http://extremecomponents.org/forum/viewtopic.php?t=139&highlight=chinese+filter


这是我在JavaEye的一篇帖子,转到我的Blog上来。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值