文章介绍

1 制作一个xml实例
2 制作一个XSLT(fo)式样单
3 将XML文档通过XSLT转换成XSL-FO
4 采用FOP将上述文档转换成PDF格式
5 总结与思考

预备知识语法库

xml 与 xsl(fo)
<?xml version="1.0" encoding="UTF-8"?>
<!--如果xml+xslt(fo)可以不写  |     如果xml+xsl可以写,当你oxygen运行时它会帮你调浏览器-->
<?xml-stylesheet type="text/xsl" href="Sample.xsl" ?>
<ItemListReport><ReportHeader><Title>明确条款</Title><PartyA>TEAM-AG</PartyA><PartyB>编程公园技术有限公司</PartyB></ReportHeader><ReportBody><Table><TableRow><ItemName>附加条款</ItemName><ItemTime>2022-5-12 09:03</ItemTime></TableRow><TableRow><ItemName>编程公园技术有限公司(bj)</ItemName><ItemTime>2022-12-23 09:03</ItemTime></TableRow><TableRow><ItemName>编程公园技术有限公司(cd)</ItemName><ItemTime>2023-2-23 09:03</ItemTime></TableRow><TableRow><ItemName>编程公园技术有限公司(sh)</ItemName><ItemTime>2025-11-3 09:03</ItemTime></TableRow><TableRow><ItemName>编程公园技术有限公司(sz)</ItemName><ItemTime>2026-2-23 09:03</ItemTime></TableRow></Table></ReportBody><ReportFooter><PrintDate>2032-5-1</PrintDate><ReportNo>010-68273773</ReportNo></ReportFooter>
</ItemListReport>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo"><!-- 根元素  --><xsl:template match="/"><xsl:apply-templates select="ItemListReport" /></xsl:template><!--主模板//--><xsl:template match="ItemListReport"><xsl:processing-instruction name="cocoon-format">type="text/xslfo"</xsl:processing-instruction><!--在此可以定义一些全局的风格信息,如字体等--><fo:root font-family="SimSun" xmlns:fo="http://www.w3.org/1999/XSL/Format"><!--版面定义//--><fo:layout-master-set><fo:simple-page-master master-name="main" margin-top="1cm" margin-bottom="1cm" margin-left="1cm" margin-right="1cm"><!--主体//--><fo:region-body margin-top="1cm" margin-bottom="1cm" /><!--页眉//--><fo:region-before extent="1cm" /><!--页脚//--><fo:region-after extent="1cm" /></fo:simple-page-master></fo:layout-master-set><fo:page-sequence master-reference="main"><!--页眉显示内容--><fo:static-content flow-name="xsl-region-before"><fo:block font-size="10pt" text-align="end" line-height="12pt">PDF 报表样例</fo:block><!-- <fo:block text-align="end"><fo:external-graphic src="report/sample/title.jpg"/></fo:block> --></fo:static-content><!--页脚显示内容--><fo:static-content flow-name="xsl-region-after"><fo:block line-height="10pt" font-size="10pt" text-align="center">共<fo:page-number-citation ref-id="endofdoc"/>页<xsl:text>       </xsl:text>第<fo:page-number/>页</fo:block></fo:static-content><!--页面主体内容--><fo:flow flow-name="xsl-region-body"><!--报表头--><xsl:apply-templates select="ReportHeader" /><!--报表体(若有多个部分内容,参照下面一行重复)--><xsl:apply-templates select="ReportBody" /><!--报表尾--><xsl:apply-templates select="ReportFooter" /></fo:flow></fo:page-sequence></fo:root></xsl:template><!--报表头//--><xsl:template match="ReportHeader"><!--标题--><fo:block font-size="24pt" font-weight="bold" line-height="30pt" vertical-align="top"text-align-last="center" space-before.optimum="12pt"><xsl:value-of select="Title" /></fo:block><!--用一个表格来格式化显示其余信息--><fo:block font-size="12pt"><fo:table table-layout="fixed" width="100%" border-collapse="separate"><fo:table-column column-width="1.3cm" /><fo:table-column column-width="17.7cm" /><fo:table-body><fo:table-row><fo:table-cell text-align="start"><fo:block><xsl:text>甲方:</xsl:text></fo:block></fo:table-cell><fo:table-cell text-align="start"><fo:block><xsl:value-of select="PartyA" /></fo:block></fo:table-cell></fo:table-row><fo:table-row><fo:table-cell text-align="start"><fo:block><xsl:text>乙方:</xsl:text></fo:block></fo:table-cell><fo:table-cell text-align="start"><fo:block><xsl:value-of select="PartyB" /></fo:block></fo:table-cell></fo:table-row></fo:table-body></fo:table></fo:block></xsl:template><!--报表主体(一般只有一个表格)//--><xsl:template match="ReportBody"><xsl:apply-templates select="Table" /></xsl:template><!--报表尾//--><xsl:template match="ReportFooter"><fo:block font-size="12pt" line-height="15pt" text-align="start" space-before.optimum="12pt"><xsl:text>签订时间:</xsl:text><xsl:value-of select="PrintDate" /></fo:block><fo:block id="endofdoc"></fo:block><fo:block font-family="Code39Seven" font-size="14pt" line-height="18pt">*<xsl:value-of select="ReportNo" />*</fo:block></xsl:template><!--表格数据//--><xsl:template match="Table"><fo:block font-size="12pt"><fo:table table-layout="fixed" width="100%" border-collapse="separate"text-align="center" border-width="0.5pt" border-style="solid" space-before.optimum="12pt"><!-- 定义列(与实际列数严格一致) //--><fo:table-column column-width="13cm" /><fo:table-column column-width="6cm" /><!-- 定义表头 //--><fo:table-header><fo:table-row font-weight="bold" font-size="13pt" border-width="0.5pt" border-style="solid"><fo:table-cell border-color="black" border-width="0.2pt" border-style="solid"><fo:block>条款名称</fo:block></fo:table-cell><fo:table-cell border-color="black" border-width="0.2pt" border-style="solid"><fo:block>录入时间</fo:block></fo:table-cell></fo:table-row></fo:table-header><!-- 表格数据 //--><fo:table-body><xsl:apply-templates select="TableRow" /></fo:table-body></fo:table></fo:block><fo:block space-before.optimum="12pt">注:显示表格每一行的模板</fo:block></xsl:template><!--显示表格每一行的模板//--><xsl:template match="TableRow"><fo:table-row space-before.optimum="3pt"><fo:table-cell border-color="black" border-width="0.2pt" border-style="solid"><fo:block><xsl:value-of select="ItemName" /></fo:block></fo:table-cell><fo:table-cell border-color="black" border-width="0.2pt" border-style="solid"><fo:block><xsl:value-of select="ItemTime" /></fo:block></fo:table-cell></fo:table-row></xsl:template>
</xsl:stylesheet>
xml 与 xsl[知识扩展]
<?xml version="1.0" encoding="UTF-8"?>
<catalog><cd><title>Empire Burlesque</title><artist>Bob Dylan</artist><country>USA</country><company>Columbia</company><price>10.90</price><year>1985</year></cd><cd><title>Romanza</title><artist>Andrea Bocelli</artist><country>EU</country><company>Polydor</company><price>10.80</price><year>1996</year></cd><cd><title>When a man loves a woman</title><artist>Percy Sledge</artist><country>USA</country><company>Atlantic</company><price>8.70</price><year>1987</year></cd><cd><title>Black angel</title><artist>Savage Rose</artist><country>EU</country><company>Mega</company><price>10.90</price><year>1995</year></cd><cd><title>1999 Grammy Nominees</title><artist>Many</artist><country>USA</country><company>Grammy</company><price>10.20</price><year>1999</year></cd><cd><title>For the good times</title><artist>Kenny Rogers</artist><country>UK</country><company>Mucik Master</company><price>8.70</price><year>1995</year></cd><cd><title>Big Willie style</title><artist>Will Smith</artist><country>USA</country><company>Columbia</company><price>9.90</price><year>1997</year></cd></catalog>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body><h2>My CD Collection</h2><table border="1"><tr bgcolor="#9acd32"><th style="text-align:left">Title</th><th style="text-align:left">Artist</th></tr><xsl:for-each select="catalog/cd"><tr><td><xsl:value-of select="title"/></td><td><xsl:value-of select="artist"/></td></tr></xsl:for-each></table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
xml 与 xsd(Schema )[知识扩展]
<?xml version="1.0" encoding="ISO-8859-1"?><persons xmlns="http://www.w3schools.com"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.mynamespace.com children.xsd http://www.w3schools.com family.xsd"><person><firstname>Hege</firstname><lastname>Refsnes</lastname><children xmlns="http://www.mynamespace.com"><childname>Cecilie</childname></children></person><person><firstname>Stale</firstname><lastname>Refsnes</lastname></person></persons>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"targetNamespace="http://www.w3schools.com"xmlns="http://www.w3schools.com"elementFormDefault="qualified"><xs:element name="persons"><xs:complexType>          <xs:sequence>   <xs:element ref="person" minOccurs="1" maxOccurs="unbounded"/>               </xs:sequence>     </xs:complexType></xs:element><xs:element name="person"><xs:complexType><xs:sequence><xs:element name="firstname" type="xs:string"/><xs:element name="lastname" type="xs:string"/><xs:any minOccurs="0"/></xs:sequence></xs:complexType>
</xs:element></xs:schema>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"targetNamespace="http://www.mynamespace.com"xmlns="http://www.mynamespace.com"elementFormDefault="qualified"><xs:element name="children"><xs:complexType><xs:sequence><xs:element name="childname" type="xs:string"maxOccurs="unbounded"/></xs:sequence></xs:complexType></xs:element></xs:schema>
xml 与 xsd(schema)(添加属性 )[知识扩展]
<?xml version="1.0" encoding="UTF-8"?>
<articles xmlns="http://www.w3schools.com"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.w3schools.com News.xsd" ><article><Title>蝗灾肆虐 数十年罕见:东非多国遭大量蝗虫入侵</Title><Date>2002-02-14T17:45:10</Date><linkexplain link="http://www.chinanews.com/gj/shipin/cns/2020/02-11/news847505.shtml">资料视频:一天吞噬3400万人的粮食!沙漠蝗虫群入侵非洲之角来源:中国新闻网</linkexplain><content1> 中新网2月14日电 据“中央社”报道,位于东非的埃塞俄比亚南部、肯尼亚部分地区正遭受蝗灾入侵,蝗虫数量庞大数十年仅见,眼见数十亿蝗虫大军逼进当地粮仓,却只有零星8架飞机可喷药,让专家急得像热锅上的蚂蚁。</content1><image src="/Users/atom-g/XML/exam/测试1/photo_example.jpg" /><content2>资料图:当地时间2020年1月21日,在肯尼亚Archers Post附近的拉里索罗村,蝗虫飞过灌木丛。《华盛顿邮报》报道称,这批蝗虫远看像是滚滚浓烟,接近后这数十亿蝗虫又像难以计数的雨点。据报道,在饱经战乱的也门与索马里,政府控制区外的地带成了蝗虫大军的温床,与气候变迁导致的印度洋厄尔尼诺现象带来季节异常的降雨,让这个区域更利蝗虫滋长。蝗虫吞噬农田、市场无物可卖、牲口无物可吃,非洲东部已有约1900万人面临高度食物短缺危机。在埃塞俄比亚首都亚的斯亚贝巴的联合国粮农组织害虫防控专家巴耶说,“我们唯一的选项就是把它们全杀光。”埃塞俄比亚北部1954年也遇过程度类似的蝗灾,当时蝗虫摧毁近乎当地百分之百的绿叶植被,加上又遇干旱,发生长达一年饥荒。尽管科技已有进步,但控制蝗害仍不乐观,因为大量的蝗虫在也门与索马里沿岸平原的沙地孵化,埃塞俄比亚却只有3架可用的飞机能喷药,肯尼亚也只有5架。蝗虫大军正逐日进逼位于东非大裂谷的埃塞俄比亚粮仓。空中喷药的最佳时机是蝗虫大军还停在地面,由于蝗虫是冷血生物,在白天变暖前几无活动力,因此清晨是最佳喷药时机;可不幸的是,频繁的晨雨多次阻碍空中喷药,等飞机升空时,蝗虫大军早已在空中。埃塞俄比亚政府雇佣私人公司的喷药飞行员说,“它们靠上升气流飞达约914米高,数量多到能阻塞飞机进气口,其实这样很危险。”近期某日,当这名飞行员结束喷药任务后,飞机全身已满是虫击的黏液,多到连挡风玻璃都已看不清楚。联合国表示,应立即投入7600万美元增强当地空中喷药能力。巴耶说,“2020可谓蝗害之年;我们不能坐以待毙,否则整个区域都会被蝗灾吞没,就会变成一个很大、很大的危机。”</content2><Author>编辑:李弘宇</Author>  </article>
</articles>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="http://www.w3schools.com"xmlns="http://www.w3schools.com"elementFormDefault="qualified"> <xs:element name="articles"><xs:complexType><xs:sequence><xs:element ref="article" minOccurs="1" maxOccurs="unbounded"/></xs:sequence></xs:complexType>
</xs:element><xs:element name="article"><xs:complexType><xs:sequence><xs:element ref="Title" minOccurs="1" maxOccurs="1"/><xs:element ref="Date" minOccurs="1" maxOccurs="1"/><xs:element ref="linkexplain" minOccurs="1" maxOccurs="1"/><xs:element ref="content1" minOccurs="0" maxOccurs="1"/><xs:element ref="image" minOccurs="0" maxOccurs="1"/><xs:element ref="content2" minOccurs="1" maxOccurs="1"/><xs:element ref="Author" minOccurs="1" maxOccurs="1"/></xs:sequence></xs:complexType></xs:element><xs:element name="Title" type="xs:string"/><xs:element name="Date" type="xs:dateTime"/><xs:element name="linkexplain"><xs:complexType><xs:simpleContent><xs:extension base="xs:string"><xs:attribute name="link" type="xs:anyURI"/></xs:extension></xs:simpleContent></xs:complexType></xs:element><xs:element name="content1" type="xs:string"/><xs:element name="image"><xs:complexType><xs:attribute name="src" type="xs:anyURI"/></xs:complexType></xs:element><xs:element name="content2" type="xs:string"/><xs:element name="Author" type="xs:string"/></xs:schema>
xml 与 xsl(添加图片 )[知识扩展]
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="pictest.xsl"?>
<image><image-clear1 src="/Users/atom-g/XML/exam/测试1/photo_example.jpg" width="555" height="440"/>
</image>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:xs="http://www.w3.org/2001/XMLSchema"exclude-result-prefixes="xs"version="1.0"><xsl:template match="image"><img><xsl:attribute name="src"><xsl:value-of select="image-clear1/@src"/></xsl:attribute><xsl:attribute name="width"><xsl:value-of select="image-clear1/@width"/></xsl:attribute><xsl:attribute name="height"><xsl:value-of select="image-clear1/@height"/></xsl:attribute></img></xsl:template></xsl:stylesheet>

xml转PDF

1 制作一个xml实例

<?xml version="1.0" encoding="UTF-8"?><article><Title>蝗灾肆虐 数十年罕见:东非多国遭大量蝗虫入侵</Title><Date>2002-02-14T17:45:10</Date><linkexplain link="http://www.chinanews.com/gj/shipin/cns/2020/02-11/news847505.shtml">资料视频:一天吞噬3400万人的粮食!沙漠蝗虫群入侵非洲之角来源:中国新闻网</linkexplain><content1> 中新网2月14日电 据“中央社”报道,位于东非的埃塞俄比亚南部、肯尼亚部分地区正遭受蝗灾入侵,蝗虫数量庞大数十年仅见,眼见数十亿蝗虫大军逼进当地粮仓,却只有零星8架飞机可喷药,让专家急得像热锅上的蚂蚁。</content1><image><image_1 src="/Users/atom-g/XML/exam/测试2/photo_example.jpg" width="555" height="440" /></image><content2>资料图:当地时间2020年1月21日,在肯尼亚Archers Post附近的拉里索罗村,蝗虫飞过灌木丛。《华盛顿邮报》报道称,这批蝗虫远看像是滚滚浓烟,接近后这数十亿蝗虫又像难以计数的雨点。据报道,在饱经战乱的也门与索马里,政府控制区外的地带成了蝗虫大军的温床,与气候变迁导致的印度洋厄尔尼诺现象带来季节异常的降雨,让这个区域更利蝗虫滋长。蝗虫吞噬农田、市场无物可卖、牲口无物可吃,非洲东部已有约1900万人面临高度食物短缺危机。在埃塞俄比亚首都亚的斯亚贝巴的联合国粮农组织害虫防控专家巴耶说,“我们唯一的选项就是把它们全杀光。”埃塞俄比亚北部1954年也遇过程度类似的蝗灾,当时蝗虫摧毁近乎当地百分之百的绿叶植被,加上又遇干旱,发生长达一年饥荒。尽管科技已有进步,但控制蝗害仍不乐观,因为大量的蝗虫在也门与索马里沿岸平原的沙地孵化,埃塞俄比亚却只有3架可用的飞机能喷药,肯尼亚也只有5架。蝗虫大军正逐日进逼位于东非大裂谷的埃塞俄比亚粮仓。空中喷药的最佳时机是蝗虫大军还停在地面,由于蝗虫是冷血生物,在白天变暖前几无活动力,因此清晨是最佳喷药时机;可不幸的是,频繁的晨雨多次阻碍空中喷药,等飞机升空时,蝗虫大军早已在空中。埃塞俄比亚政府雇佣私人公司的喷药飞行员说,“它们靠上升气流飞达约914米高,数量多到能阻塞飞机进气口,其实这样很危险。”近期某日,当这名飞行员结束喷药任务后,飞机全身已满是虫击的黏液,多到连挡风玻璃都已看不清楚。联合国表示,应立即投入7600万美元增强当地空中喷药能力。巴耶说,“2020可谓蝗害之年;我们不能坐以待毙,否则整个区域都会被蝗灾吞没,就会变成一个很大、很大的危机。”</content2><Author>编辑:李弘宇</Author></article>

2 制作一个XSLT(fo)式样单

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0"><!--  Template for root element 'News'  --><xsl:template match="article"><fo:root font-family="SimSun" xmlns:fo="http://www.w3.org/1999/XSL/Format"><fo:layout-master-set><fo:simple-page-master master-name="one" page-height="12cm" page-width="21cm" margin-left="0cm" margin-right="0cm"><fo:region-body/></fo:simple-page-master></fo:layout-master-set><fo:page-sequence master-reference="one"><fo:flow flow-name="xsl-region-body" font-size="10pt" line-height="18pt"><xsl:apply-templates select="Title"/><fo:block text-align="justify" margin-left="0cm" margin-right="0cm" ><xsl:apply-templates select="Date"/><xslt:apply-templates select="linkexplain"/><xslt:apply-templates select="content1"/><xslt:apply-templates select="image"/><xslt:apply-templates select="content2"/> </fo:block>                   <xslt:apply-templates select="Author"/>           </fo:flow></fo:page-sequence></fo:root></xsl:template><!--  Template for element type 'Title'  --><xsl:template match="Title"><fo:block text-align="center" font-size="24pt" font-weight="bold" color="black" line-height="28pt" ><xsl:apply-templates/></fo:block></xsl:template><!--  Template for element type 'Date| linkexplain'  --><xslt:template match="Date "><fo:inline font-size="7pt" margin-left="2cm"><xslt:apply-templates/></fo:inline></xslt:template><xslt:template match="linkexplain "><fo:block text-align="center"><fo:inline font-size="7pt" margin-left="1cm" ><xslt:apply-templates/></fo:inline></fo:block></xslt:template><!--  Template for element type 'content1'  --><xslt:template match="content1"><fo:block  margin-left="0cm" margin-right="0cm"><fo:inline font-weight="bold"><xslt:apply-templates/></fo:inline></fo:block></xslt:template><!--  Template for element type 'image'  --><xsl:template match="image"><fo:block margin-left="5cm" margin-right="0cm" ><fo:external-graphic src="/Users/atom-g/XML/exam/测试2/photo_example.jpg"/></fo:block></xsl:template><!--  Template for element type 'content2'  --><xslt:template match="content2"><fo:block text-align="center"  margin-left="0cm" margin-right="1cm" margin-top="2com"><fo:inline font-weight="bold"><xslt:apply-templates/></fo:inline></fo:block></xslt:template><xslt:template match="Author"><fo:block text-align="right" margin-top="1com"><xslt:apply-templates/></fo:block></xslt:template></xsl:stylesheet>

3 将XML文档通过XSLT转换成XSL-FO

用此命令去生成fo:
xsltproc -o /Users/atom-g/XML/exam/测试2/News_t2.fo /Users/atom-g/XML/exam/测试2/News_xslt.xsl /Users/atom-g/XML/exam/测试2/News.xml

4 采用FOP将上述文档转换成PDF格式
这里兵分两路,两种办法但是殊途同归
方法1 - 命令行

//下载fop  //会下载到/usr/local/Cellar(这里是隐藏文件,记得用Command + Shift + . 使其现身)
1   brew install fop
2   cmd输入 fop       //看看你想如何命令它把
3   fop -xml /Users/atom-g/XML/exam/测试2/News.xml -xsl /Users/atom-g/XML/exam/测试2/News_xslt.xsl -pdf /Users/atom-g/XML/exam/测试2/News_readonly.pdf    //输出(英文)



这里需要注意,用TEAM-AG配置好的独家配方包

//下载fop  //会下载到/usr/local/Cellar(这里是隐藏文件,记得用Command + Shift + . 使其现身)
1   brew install fop
2   cmd输入 fop                //看看你想如何命令它把   ****这条指令是要求 fop 去找 fop.xconf 读那里面的配置信息 通过fop.xconf里的配置信息输出****
3   fop -c /usr/local/Cellar/fop/2.4_2/libexec/fop/conf/fop.xconf /Users/atom-g/XML/exam/测试2/News.fo -pdf /Users/atom-g/XML/exam/测试2/ReadOnly_cmd.pdf     //输出(中文)

方法2 - java

项目完整包我已放在上传文件中 名为:xml转PDF_完整项目_CodingPark

package com.cisetech.put.utils.fop;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;/*** FopReport* @author bin.yin 2012/12/23*/
public class FopReport {private static Logger log = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG);// Step 1: Construct a FopFactoryprivate static final FopFactory fopFactory = FopFactory.newInstance();/*** 根据xsl模板及xml数据文件生成pdf* @param xsltFile xsl模板* @param xmlFile xml数据文件* @return ReportData* @throws Exception* @author TEAM-AG*/public static ReportData createReport(String xsltFile, String xmlFile) throws Exception {ReportData reportData = new ReportData();reportData.setContentType("application/pdf");fopFactory.setUserConfig("conf/fop.xml");// Step 2: Set up output stream.ByteArrayOutputStream out = new ByteArrayOutputStream();try {// Step 3: Construct fop with desired output formatFop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);// Step 4: Setup XSLT using identity transformerTransformerFactory factory = TransformerFactory.newInstance();Transformer transformer = factory.newTransformer(new StreamSource(new File(xsltFile)));// Step 5: Setup input and output for XSLT transformationSource src = new StreamSource(new File(xmlFile));// Source src = new StreamSource(new StringReader(myString));// Step 6: Resulting SAX events (the generated FO) must be piped through to FOPResult res = new SAXResult(fop.getDefaultHandler());// Step 7: Start XSLT transformation and FOP processingtransformer.transform(src, res);reportData.setData(out.toByteArray());} catch(Exception e) {throw e;} finally {out.close();}return reportData;}/*** 根据xsl模板及xml字节数组生成pdf* @param xsltFile xsl模板* @param bXmlData xml字节数组 eg. StringBuffer buf = new StringBuffer(); buf.getBytes("UTF-8");* @return ReportData* @throws Exception* @author TEAM-AG*/public static ReportData createReport(String xsltFile, byte[] bXmlData) throws Exception {ReportData reportData = new ReportData();try {// convert xml bytes to a temp fileFile xmlFile = File.createTempFile("FOP", ".tmp");FileOutputStream fos = new FileOutputStream(xmlFile);fos.write(bXmlData);fos.close();reportData = createReport(xsltFile, xmlFile.getAbsolutePath());// delete temp filexmlFile.delete();} catch (Exception e) {throw e;}return reportData;}public static void main(String[] args) {long t0 = System.currentTimeMillis();try {StringBuffer buf = new StringBuffer();buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");buf.append("<article>");buf.append("    <Title>蝗灾肆虐 数十年罕见:东非多国遭大量蝗虫入侵</Title>");buf.append("        <Date>   2002-02-14T17:45:10</Date>");buf.append("        <linkexplain link=\"http://www.chinanews.com/gj/shipin/cns/2020/02-11/news847505.shtml\">资料视频:一天吞噬3400万人的粮食!沙漠蝗虫群入侵非洲之角来源:中国新闻网</linkexplain>");buf.append("         <content1> 中新网2月14日电 据“中央社”报道,位于东非的埃塞俄比亚南部、肯尼亚部分地区正遭受蝗灾入侵,蝗虫数量庞大数十年仅见,眼见数十亿蝗虫大军逼进当地粮仓,却只有零星8架飞机可喷药,让专家急得像热锅上的蚂蚁。</content1>");buf.append("      <image>");buf.append("    <image_1 src=\"/Users/atom-g/XML/exam/测试2/photo_example.jpg\" width=\"555\" height=\"440\" />");buf.append("        </image>");buf.append("            <content2>资料图:当地时间2020年1月21日,在肯尼亚Archers Post附近的拉里索罗村,蝗虫飞过灌木丛。\n" +"              《华盛顿邮报》报道称,这批蝗虫远看像是滚滚浓烟,接近后这数十亿蝗虫又像难以计数的雨点。\n" +"              据报道,在饱经战乱的也门与索马里,政府控制区外的地带成了蝗虫大军的温床,与气候变迁导致的印度洋厄尔尼诺现象带来季节异常的降雨,让这个区域更利蝗虫滋长。蝗虫吞噬农田、市场无物可卖、牲口无物可吃,非洲东部已有约1900万人面临高度食物短缺危机。\n" +"              在埃塞俄比亚首都亚的斯亚贝巴的联合国粮农组织害虫防控专家巴耶说,“我们唯一的选项就是把它们全杀光。”\n" +"              埃塞俄比亚北部1954年也遇过程度类似的蝗灾,当时蝗虫摧毁近乎当地百分之百的绿叶植被,加上又遇干旱,发生长达一年饥荒。\n" +"              尽管科技已有进步,但控制蝗害仍不乐观,因为大量的蝗虫在也门与索马里沿岸平原的沙地孵化,埃塞俄比亚却只有3架可用的飞机能喷药,肯尼亚也只有5架。蝗虫大军正逐日进逼位于东非大裂谷的埃塞俄比亚粮仓。\n" +"              空中喷药的最佳时机是蝗虫大军还停在地面,由于蝗虫是冷血生物,在白天变暖前几无活动力,因此清晨是最佳喷药时机;可不幸的是,频繁的晨雨多次阻碍空中喷药,等飞机升空时,蝗虫大军早已在空中。\n" +"              埃塞俄比亚政府雇佣私人公司的喷药飞行员说,“它们靠上升气流飞达约914米高,数量多到能阻塞飞机进气口,其实这样很危险。”近期某日,当这名飞行员结束喷药任务后,飞机全身已满是虫击的黏液,多到连挡风玻璃都已看不清楚。\n" +"              联合国表示,应立即投入7600万美元增强当地空中喷药能力。\n" +"            巴耶说,“2020可谓蝗害之年;我们不能坐以待毙,否则整个区域都会被蝗灾吞没,就会变成一个很大、很大的危机。”\n" +"        </content2>");buf.append("               <Author>编辑:李弘宇</Author>");buf.append("                </article>");long t = System.currentTimeMillis();System.out.println("检查点1");
//          ReportData data = FopReport.createReport("report/sample/News_xslt.xsl", buf.toString().getBytes("UTF-8"));ReportData data = FopReport.createReport("report/sample/News_xslt.xsl", "report/sample/News.xml");System.out.println("检查点2");long t1 = System.currentTimeMillis();log.debug("time:" + (t1 - t));FileOutputStream fos = new FileOutputStream("/Users/atom-g/XML/exam/测试2/ReadOnly.pdf");fos.write(data.getData());fos.close();} catch (Exception e) {e.printStackTrace();}log.debug("use time:" + (System.currentTimeMillis() - t0));}
}
package com.cisetech.put.utils.fop;import java.io.Serializable;/*** <p>Title: </p>* <p>Description: </p>* @author TEAM-AG* @version 1.0*/
public class ReportData implements Serializable {private static final long serialVersionUID = -2722248902864797698L;private byte[] mbData = null;private String msContentType = null;public byte[] getData() {return mbData;}public void setData(byte[] pData) {mbData = pData;}public String getContentType() {return msContentType;}public void setContentType(String pContentType) {msContentType = pContentType;}
}

5 总结与思考

1 中文乱码问题 xsl(fo) 中大有学问


结果展示:左java输出|右cmd输出

2 相关文章推荐

http://www.linkwerk.com/pub/xml/invitation/xml2pdf/ 【相关案例】
https://blog.csdn.net/resuce/article/details/80215678 【相关案例】
https://blog.csdn.net/QQ694885382/article/details/81044007 【如何使用相对路径,./、…/、…/…/】

3 特别鸣谢

ZhanWen
BaiFeng
ZhaoXu
HuChuan

xml转PDF(xmlxslt-」fo-」pdf)_完整项目_CodingPark编程公园相关推荐

  1. 2行代码用 Python「剪藏」网页为 PDF

    不知道你有没有这样的场景,在网页上看到一篇很好的文章,你就很想把它保存下来,并对其中重要的内容进行高亮标记. 这样的工具有很多,像「印象笔记」就可以"剪藏"网页内容到笔记中. 不过 ...

  2. Python「剪藏」网页为 PDF

    简介 Python 的第三方库pdfkit ,这个模块可以将网页.html 文件以及字符串生成pdf文件. 把我们想要的网页保存到本地PDF文件,再结合PDF神器(Adobe Acrobat Pro ...

  3. 分享一款手机端的PDF文件编辑软件「PDF处理助手」简单、免费

    今天给大家来一款手机端的PDF文件编辑神器,"PDF处理助手",不过这款软件目前只有Android端的喔,ios的小伙伴有需要的话可以直接去Appstore搜索[pdf]下载相关的 ...

  4. pdf文档补丁,pdf编辑,去除pdf文件限制

    哈喽,大家好!我是指北君. 在我们的日常生活中,PDF文档是我们除了Office外经常需要接触的文件格式.很多时候,我们都需要能对PDF文档进行一些处理,比如编辑文字.拆分/合并文档.生成书签.提取图 ...

  5. 【转】如何管理PDF书签:Foxit、PDF XChange、PDF补丁丁

    [摘要]本文对PDF的书签功能进行简单分析,并提供Foxit Reader.PDF XChange Viewer.PDF补丁丁等解决方案. 一.PDF书签功能简析 正文开始之前,我认为很有必要指出:P ...

  6. pdf在线解密,忘记pdf密码怎么办?

    pdf解开加密在线,pdf权限限制如何解除?[亲测好用]解开pdf编辑,用「密码帝」 无需下载安装软件,手机电脑都可以,一键轻松在线解密,百度搜索密码帝就可以了!

  7. pdf阅读器,pdf阅读器大全,最好pdf阅读器排行,pdf阅读器下载

    pdf阅读器第一名:Adobe Reader V8.1.0 简体中文版 PDF (Portable Document Format)文件格式是电子发行文档的事实上的标准,Adobe Acrobat R ...

  8. 免费开源好用还佛系的国产PDF软件:pdf补丁丁下载 | 含pdf补丁丁使用手册

    PDF补丁丁(PDFPatcher)是一款绿色免费开源且完全免费的多功能国产PDF软件,基于.NET Framework开发,主要采用 iText和MuPDF这两个开放源代码的组件库来处理PDF文件, ...

  9. POI根据模板导出word文件,以及word转PDF,PDF转图片再插入PDF中(防止PDF被修改)

    POI操作word和PDF POI根据模板导出word文件 word转PDF PDF转图片再插入PDF中(防止PDF被修改) POI根据模板导出word文件 一.制作word模版,${xxxx}是一会 ...

  10. Itext生成pdf文件,itext+Freemarker生成pdf,(中文空白解决)

    来源:https://my.oschina.net/lujianing/blog/894365 1.背景 在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中转账的电子回单,签约的电子合同等. ...

最新文章

  1. css实战笔记(一):写网页前的reset工作
  2. startos 5.1 如何 root 登陆
  3. http协议状态码和web错误解决总结
  4. 转:shell awk
  5. 走向无后端的系统开发实践:CRUD自动化与强约定的REST接口
  6. 不重复地输出数(信息学奥赛一本通-T1245)
  7. [Java] 蓝桥杯PREV-8 历届试题 买不到的数目
  8. IntelliJ IDEA如何去掉xml文件背景色
  9. T分布和T检验的理解,Python代码实现T检验的计算
  10. Java基础知识笔记
  11. LDO使用之热阻考虑
  12. python的super super easy教程 | 类
  13. c语言中循环并列语句顺序,C语言第五讲,语句 顺序循环选择.
  14. criteria 用法
  15. Windows驱动开发之第一个驱动程序
  16. evus是什么意思_去美国之前要上网做evus是什么意思
  17. 2022年ISO27001资质认证补贴政策汇总
  18. 服务器管理器正在收集清单数据_数据仓库快速入门教程1简介
  19. 请这样回答双向数据绑定原理
  20. cad跨图纸复制不了怎么解决?

热门文章

  1. Android 校正系统时间的三种解决方案
  2. html tooltips效果,div+css样式自制带小三角的tooltips效果
  3. UINO优锘:深度|扒一扒图化资源申请之三生三世那点事儿
  4. Flash Player去广告下载地址
  5. ice中间件 java_ICE中间件介绍以及demo
  6. DSP28377 I2C开发笔记
  7. git创建本地ssh密匙
  8. javawebJAVAJSP酒店预订系统jsp酒店管理系统jsp民宿预订酒店jsp客房预订系统jsp宾馆客房预订系统
  9. legacy引导gpt分区_装系统用什么分区?gpt分区及mbr分区详细教程(附带bios设置)
  10. Toast调整显示位置