xml转PDF(xml&xslt->fo->pdf)_完整项目_CodingPark编程公园

文章介绍

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

预备知识语法库

xml 与 xsl(fo)


 
<ItemListReport>
	<ReportHeader>
		<Title>明确条款Title>
		<PartyA>TEAM-AGPartyA>
		<PartyB>编程公园技术有限公司PartyB>
	ReportHeader>
	<ReportBody>
		<Table>
			<TableRow>
				<ItemName>附加条款ItemName>
				<ItemTime>2022-5-12 09:03ItemTime>
			TableRow>
			<TableRow>
				<ItemName>编程公园技术有限公司(bj)ItemName>
				<ItemTime>2022-12-23 09:03ItemTime>
			TableRow>
			<TableRow>
				<ItemName>编程公园技术有限公司(cd)ItemName>
				<ItemTime>2023-2-23 09:03ItemTime>
			TableRow>
			<TableRow>
				<ItemName>编程公园技术有限公司(sh)ItemName>
				<ItemTime>2025-11-3 09:03ItemTime>
			TableRow>
			<TableRow>
				<ItemName>编程公园技术有限公司(sz)ItemName>
				<ItemTime>2026-2-23 09:03ItemTime>
			TableRow>
		Table>
	ReportBody>
	<ReportFooter>
		<PrintDate>2032-5-1PrintDate>
		<ReportNo>010-68273773ReportNo>
	ReportFooter>
ItemListReport>

<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: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[知识扩展]

<catalog>
  <cd>
    <title>Empire Burlesquetitle>
    <artist>Bob Dylanartist>
    <country>USAcountry>
    <company>Columbiacompany>
    <price>10.90price>
    <year>1985year>
  cd>
  <cd>
    <title>Romanzatitle>
    <artist>Andrea Bocelliartist>
    <country>EUcountry>
    <company>Polydorcompany>
    <price>10.80price>
    <year>1996year>
  cd>
  <cd>
    <title>When a man loves a womantitle>
    <artist>Percy Sledgeartist>
    <country>USAcountry>
    <company>Atlanticcompany>
    <price>8.70price>
    <year>1987year>
  cd>
  <cd>
    <title>Black angeltitle>
    <artist>Savage Roseartist>
    <country>EUcountry>
    <company>Megacompany>
    <price>10.90price>
    <year>1995year>
  cd>
  <cd>
    <title>1999 Grammy Nomineestitle>
    <artist>Manyartist>
    <country>USAcountry>
    <company>Grammycompany>
    <price>10.20price>
    <year>1999year>
  cd>
  <cd>
    <title>For the good timestitle>
    <artist>Kenny Rogersartist>
    <country>UKcountry>
    <company>Mucik Mastercompany>
    <price>8.70price>
    <year>1995year>
  cd>
  <cd>
    <title>Big Willie styletitle>
    <artist>Will Smithartist>
    <country>USAcountry>
    <company>Columbiacompany>
    <price>9.90price>
    <year>1997year>
  cd>
  
catalog>



<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html> 
<body>
  <h2>My CD Collectionh2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">Titleth>
      <th style="text-align:left">Artistth>
    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 )[知识扩展]


<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>Hegefirstname>
        <lastname>Refsneslastname>
        <children xmlns="http://www.mynamespace.com">
            <childname>Ceciliechildname>
        children>
    person>
    
    <person>
        <firstname>Stalefirstname>
        <lastname>Refsneslastname>
    person>
    
persons>

<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>

<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)(添加属性 )[知识扩展]

<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:10Date>
        <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>


<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(添加图片 )[知识扩展]


<image>
    <image-clear1 src="/Users/atom-g/XML/exam/测试1/photo_example.jpg" width="555" height="440"/>
image>

<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实例


    
<article>
    
        <Title>蝗灾肆虐 数十年罕见:东非多国遭大量蝗虫入侵Title>
        <Date>2002-02-14T17:45:10Date>
        <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)式样单


<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">

    
    
    <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>
    
    
    <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>
    
    
    <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>
    
    
    <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>
    
    
    <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>
    
    
    <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(xml&xslt->fo->pdf)_完整项目_CodingPark编程公园_第1张图片
项目完整包我已放在上传文件中 名为: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 FopFactory
	private 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 format
			Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

			// Step 4: Setup XSLT using identity transformer
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer transformer = factory.newTransformer(new StreamSource(new File(xsltFile)));

			// Step 5: Setup input and output for XSLT transformation
			Source 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 FOP
			Result res = new SAXResult(fop.getDefaultHandler());

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

/**
 * 

Title:

*

Description:

* @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) 中大有学问
xml转PDF(xml&xslt->fo->pdf)_完整项目_CodingPark编程公园_第2张图片
xml转PDF(xml&xslt->fo->pdf)_完整项目_CodingPark编程公园_第3张图片
结果展示:左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(xml&xslt->fo->pdf)_完整项目_CodingPark编程公园_第4张图片

你可能感兴趣的:(帮助手册)