分享
 
 
 

XML文件到RTF和PDF的转换

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

Author: Holyfair

E-Mail: Holyfair@sina.com

一. 序 在一些运用中,我们通常会把一些文本和配置信息转换成XML文件进行传输,修改,保存.特别是具有一定模板性质的文档用XML文件来实现其管理就显得相当的方便了.提供对于XML文件的操作的java API很多,诸于DOM,JDOM,Castor,SAX,XMLReader,XPath,XSLT等等. 具体的这些API的用法这里就不多提了. 当使用这些接口实现XML的操作后,对于有些文档而言最终必须呈现给用户看的还是我们通常所熟悉的WORD和PDF文档.我们这里就来看一下从一个XML文件到RTF和PDF文件转换的实现.

二. 从XML到PDF 对于一个具有一定模板性质的XML文件,我们可以用FOP API来实现其到PDF的转换.

FOP需要fop.jar. 我们可以到http://xml.apache.org/fop/ 上获取和了解其用法.

以一个一般复杂的XML文件为例:

要转换XML文档 test.xml 如下:

<FeatureSRS title="SRS">

<introduction>

<objective>objective here</objective>

<scope>scope here</scope>

<responsibilities>responsibilities here</responsibilities>

<references>reference here</references>

<DAA>

<term>

term here

</term>

<definition>

definition here

</definition>

</DAA>

</introduction>

<generalDescription>

<featureName>

<summary>summary here</summary>

<breakdown>breakdown here</breakdown>

</featureName>

<requirement>

<content>

content here.

</content>

</requirement>

<requirement>

<content>

content2 here.

</content>

</requirement>

<featureInteractions>featureInteractions here</featureInteractions>

</generalDescription>

<strResources>

<strResource>

<estring>

estring here

</estring>

<resourceid>

resourceid here

</resourceid>

<rqmt>

rqmt here.

</rqmt>

</strResource>

</strResources>

</FeatureSRS>

对于这样一个XML文档,我们要将其转化成PDF格式必须建立一个XSL-FO文件,来定义对各element和value格

式的转换.

我们建立XSL-FO文件 test.xsl 如下:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">

<xsl:output method="xml" version="1.0" omit-xml-declaration="no" indent="yes"/>

<!-- ========================= -->

<!-- root element: projectteam -->

<!-- ========================= -->

<xsl:template match="FeatureSRS">

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

<fo:layout-master-set>

<fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">

<fo:region-body/>

</fo:simple-page-master>

</fo:layout-master-set>

<fo:page-sequence master-reference="simpleA4">

<fo:flow flow-name="xsl-region-body">

<fo:block font-size="20pt" font-weight="bold" space-after="5mm" text-align="center">Cardiac Feature SRS

</fo:block>

<fo:block font-size="10pt">

<xsl:apply-templates/>

</fo:block>

</fo:flow>

</fo:page-sequence>

</fo:root>

</xsl:template>

<!-- ========================= -->

<!-- child element: member -->

<!-- ========================= -->

<xsl:template name="introduction" match="introduction">

<fo:block font-size="18pt" font-weight="bold" space-after="5mm">1. Intruction</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="5mm">1.1 Objective</fo:block>

<fo:block font-size="10pt" font-weight="normal" space-after="5mm" margin-left="7mm">

<xsl:value-of select="objective"/>

</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="5mm">1.2 Scope</fo:block>

<fo:block font-size="10pt" font-weight="normal" space-after="5mm" margin-left="7mm">

<xsl:value-of select="scope"/>

</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="5mm">1.3. Responsibilities</fo:block>

<fo:block font-size="10pt" font-weight="normal" space-after="5mm" margin-left="7mm">

<xsl:value-of select="responsibilities"/>

</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="5mm">1.4. References</fo:block>

<fo:block font-size="10pt" font-weight="normal" space-after="5mm" margin-left="7mm">

<xsl:value-of select="references"/>

</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="5mm">1.5. Definitions, Acronyms, and Abbreviations</fo:block>

<fo:block font-size="10pt" font-weight="bold" space-after="5mm" margin-left="5mm">

<fo:table table-layout="fixed" border="2cm" background-color="#fff2d9" >

<fo:table-column column-width="4cm"/>

<fo:table-column column-width="6cm"/>

<fo:table-body>

<fo:table-row border="2">

<fo:table-cell>

<fo:block>

<xsl:text>Term</xsl:text>

</fo:block>

</fo:table-cell>

<fo:table-cell>

<fo:block>

<xsl:text>Definition</xsl:text>

</fo:block>

</fo:table-cell>

</fo:table-row>

<xsl:for-each select="DAA">

<fo:table-row border="2">

<fo:table-cell>

<fo:block>

<xsl:value-of select="term"/>

</fo:block>

</fo:table-cell>

<fo:table-cell>

<fo:block>

<xsl:value-of select="definition"/>

</fo:block>

</fo:table-cell>

</fo:table-row>

</xsl:for-each>

</fo:table-body>

</fo:table>

</fo:block>

</xsl:template>

<xsl:template name="generalDescription" match="generalDescription">

<fo:block font-size="18pt" font-weight="bold" space-after="5mm">2. General Description</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="5mm">2.1. Feature Name</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="7mm">2.1.1. Feature Summary</fo:block>

<fo:block font-size="10pt" font-weight="normal" space-after="5mm" margin-left="9mm">

<xsl:value-of select="featureName/summary"/>

</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="7mm">2.1.2. Feature Breakdown</fo:block>

<fo:block font-size="10pt" font-weight="normal" space-after="5mm" margin-left="9mm">

<xsl:value-of select="featureName/breakdown"/>

</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="5mm">2.2. Feature Requirements</fo:block>

<fo:block font-size="10pt" font-weight="normal" space-after="5mm" margin-left="7mm">

<xsl:for-each select="requirement">

<xsl:value-of select="content"/>

</xsl:for-each>

</fo:block>

<fo:block font-size="14pt" font-weight="bold" space-after="5mm" margin-left="5mm">2.3. Feature Interactions</fo:block>

<fo:block font-size="10pt" font-weight="normal" space-after="5mm" margin-left="7mm">

<xsl:value-of select="featureInteractions"/>

</fo:block>

</xsl:template>

<xsl:template name="strResources" match="strResources">

<fo:block font-size="18pt" font-weight="bold" space-after="5mm">3. String Resources </fo:block>

<fo:block font-size="10pt" font-weight="bold" space-after="5mm" margin-left="5mm">

<fo:table table-layout="fixed" border="2cm" background-color="#fff2d9" >

<fo:table-column column-width="4cm"/>

<fo:table-column column-width="10cm"/>

<fo:table-column column-width="4cm"/>

<fo:table-body>

<fo:table-row border="2">

<fo:table-cell>

<fo:block>

<xsl:text>English String</xsl:text>

</fo:block>

</fo:table-cell>

<fo:table-cell>

<fo:block>

<xsl:text>Resource ID</xsl:text>

</fo:block>

</fo:table-cell>

<fo:table-cell>

<fo:block>

<xsl:text>Rqmt</xsl:text>

</fo:block>

</fo:table-cell>

</fo:table-row>

<xsl:for-each select="strResource">

<fo:table-row border="2">

<fo:table-cell>

<fo:block>

<xsl:value-of select="estring"/>

</fo:block>

</fo:table-cell>

<fo:table-cell>

<fo:block>

<xsl:value-of select="resourceid"/>

</fo:block>

</fo:table-cell>

<fo:table-cell>

<fo:block>

<xsl:value-of select="rqmt"/>

</fo:block>

</fo:table-cell>

</fo:table-row>

</xsl:for-each>

</fo:table-body>

</fo:table>

</fo:block>

</xsl:template>

</xsl:stylesheet>

其具体的XSL-FO文件格式的语法可以参照一些其他资料.

建立好了此文件之后,我们就可以用FOP提供的一些接口方便的进行转换了.

FOP提供了XML->FO,XML->PDF,FO-PDF,OBJ->FO,OBJ->PDF的转换接口.

我们这里以XML->PDF的为例,其余的可以参照FOP包里相应的DEMO.

public class ExampleXML2PDF {

public void convertXML2PDF(File xml, File xslt, File pdf)

throws IOException, FOPException, TransformerException {

Driver driver = new Driver();

Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);

driver.setLogger(logger);

MessageHandler.setScreenLogger(logger);

//Setup Renderer (output format)

driver.setRenderer(Driver.RENDER_PDF);

//Setup output

OutputStream out = new java.io.FileOutputStream(pdf);

try {

driver.setOutputStream(out);

//Setup XSLT

TransformerFactory factory = TransformerFactory.newInstance();

Transformer transformer = factory.newTransformer(new StreamSource(xslt));

//Setup input for XSLT transformation

Source src = new StreamSource(xml);

//Resulting SAX events (the generated FO) must be piped through to FOP

Result res = new SAXResult(driver.getContentHandler());

//Start XSLT transformation and FOP processing

transformer.transform(src, res);

} finally {

out.close();

}

}

public static void main(String[] args) {

try {

System.out.println("FOP ExampleXML2PDF\n");

System.out.println("Preparing...");

//Setup directories

File baseDir = new File(".");

File outDir = new File(baseDir, "out");

outDir.mkdirs();

//Setup input and output files

File xmlfile = new File(baseDir, "test.xml");

File xsltfile = new File(baseDir, "test.xsl");

File pdffile = new File(outDir, "test.pdf");

System.out.println("Input: XML (" + xmlfile + ")");

System.out.println("Stylesheet: " + xsltfile);

System.out.println("Output: PDF (" + pdffile + ")");

System.out.println();

System.out.println("Transforming...");

ExampleXML2PDF app = new ExampleXML2PDF();

app.convertXML2PDF(xmlfile, xsltfile, pdffile);

System.out.println("Success!");

} catch (Exception e) {

System.err.println(ExceptionUtil.printStackTrace(e));

System.exit(-1);

}

}

}

这样我们就很轻易地实现了XML文档到PDF文档的转换.

如果这些用在webservice的servlet中,想从xml文件直接生成pdf传输给浏览者而并不生成的pdf文件,我们可以如

下实现:

public class FOPServlet extends HttpServlet {

public static final String FO_REQUEST_PARAM = "fo";

public static final String XML_REQUEST_PARAM = "xml";

public static final String XSL_REQUEST_PARAM = "xsl";

public void doGet(HttpServletRequest request,

HttpServletResponse response) throws ServletException {

try {

String xmlParam =getServletContext().getRealPath("WEB-INF/doc/xml/test.xml");

String xslParam =getServletContext().getRealPath("WEB-INF/doc/xsl/test.xsl");

if ((xmlParam != null) && (xslParam != null)) {

XSLTInputHandler input =

new XSLTInputHandler(new File(xmlParam),

new File(xslParam));

renderXML(input, response);

} else {

PrintWriter out = response.getWriter();

out.println("<html><head><title>Error</title></head>\n"+

"<body><h1>FopServlet Error</h1><h3>No 'fo' "+

"request param given.</body></html>");

}

} catch (ServletException ex) {

throw ex;

}

catch (Exception ex) {

throw new ServletException(ex);

}

}

public void renderXML(XSLTInputHandler input,

HttpServletResponse response) throws ServletException {

try {

ByteArrayOutputStream out = new ByteArrayOutputStream();

response.setContentType("application/pdf");

Driver driver = new Driver();

driver.setRenderer(Driver.RENDER_PDF);

driver.setOutputStream(out);

driver.render(input.getParser(), input.getInputSource());

byte[] content = out.toByteArray();

response.setContentLength(content.length);

response.getOutputStream().write(content);

response.getOutputStream().flush();

} catch (Exception ex) {

throw new ServletException(ex);

}

}

}

三. XML to RTF xml到rtf的转换稍微有一些麻烦,我们没有直接从XML到RTF的API, 我们将要用的JFor API还没有整合到FOP

中去. JFor API可以实现 从 FO文件到RTF文件的转换, 它也提供了consle接口.

我们可以从 www.jfor.org 上获取jfor相关信息.

我们从XML文件到RTF文件的转换可以分为两步:

1. 用FOP将 xml 转换成 fo

2. 用JFor将 fo 转换成RTF

3.1 用FOP将 xml 转换成 fo

这一步我们可以很轻易的沿用上面所述的方法,如下实现xml到fo 的转换,依然会用到上面所用的xml文件

和xsl-fo文件.

OutputStream foOut = new FileOutputStream(fofile);

TransformerFactory factory = TransformerFactory.newInstance();

Transformer transformer = factory.newTransformer(new StreamSource(

xsltfile));

Source src = new StreamSource(xmlfile);

Result res = new StreamResult(foOut);

transformer.transform(src, res);

foOut.close();

3.2 用JFor将 fo 转换成RTF

仅以Serlvet需求的实现为例:

InputStream foInput = new FileInputStream(fofile);

InputSource inputSource = new InputSource(foInput);

ByteArrayOutputStream out = new ByteArrayOutputStream();

Writer output = new OutputStreamWriter(out);

response.setContentType("application/msword");

new Converter(inputSource,output,Converter.createConverterOption ());

output.flush();

byte[] content = out.toByteArray();

System.out.println(out.toString());

response.setContentLength(content.length);

response.getOutputStream().write(content);

response.getOutputStream().flush();

foInput.close();

output.close();

out.close();

这样我们就成功地将xml转化成了RTF格式的文件.

本文仅简述了大体的实现过程,具体的细节可参照各技术点的详细自述.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有