我正在嘗試生成一個pdf
下載文件。我有以下代碼來生成pdf從xml
和xsl-fo
。任何人都可以指出我在代碼中缺少的東西。當我打開PDF文件時,它說已損壞,如果我使用notepad++
打開該文件,則在該文件中全部顯示爲[[email protected]
。apache fop無法獲得pdf,並將正確的字節寫入
public void generatePDF(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException {
PortletContext portletContext = resourceRequest.getPortletSession().getPortletContext();
URL url = portletContext.getResource("/WEB-INF/xsd/xsl-fo.xsl");
File xsltfile = new File(url.getPath());
StreamSource source = new StreamSource(new File(portletContext.getResource("/WEB-INF/xsd/service.xml").getPath()));
StreamSource transformSource = new StreamSource(xsltfile);
// Construct FopFactory
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// Create ByteArrayOutputStream
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// Setup JAXP using identity transformer
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer xslfoTransformer;
try {
xslfoTransformer = tfactory.newTransformer(transformSource); // identity transformer
Fop fop;
try {
// Construct fop with desired output format
fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, outStream);
Result res = new SAXResult(fop.getDefaultHandler());
try {
xslfoTransformer.transform(source, res);
byte[] pdfBytes = outStream.toByteArray();
resourceResponse.setContentLength(pdfBytes.length);
resourceResponse.setContentType("application/pdf");
resourceResponse.addProperty("Content-Disposition", "attachment;filename=fleetevents.pdf");
resourceResponse.getWriter().print(pdfBytes);
resourceResponse.getWriter().flush();
} catch (TransformerException exception) {
logger.log(Level.SEVERE, exception.getMessage(), exception);
}
} catch (FOPException fopException) {
logger.log(Level.SEVERE, fopException.getMessage(), fopException);
}
} catch(TransformerConfigurationException exception) {
logger.log(Level.SEVERE, exception.getMessage(), exception);
} catch(TransformerFactoryConfigurationError exception) {
logger.log(Level.SEVERE, exception.getMessage(), exception);
}
}
我的示例XML
<?xml version="1.0" encoding="iso-8859-1"?>
<services>
<service>
<serviceId>11111</serviceId>
<openDate>2012-02-16</openDate>
<closeDate>2012-02-16</closeDate>
<orderStatus>Status2</orderStatus>
<description>INSPECT MACHINE</description>
<repairCost>$266.76</repairCost>
</service>
<service>
<serviceId>11111</serviceId>
<openDate>2012-02-16</openDate>
<closeDate>2012-02-16</closeDate>
<orderStatus>Status1</orderStatus>
<description>INSPECT MACHINE</description>
<repairCost>$266.76</repairCost>
</service>
</services>
和我的樣本XSF-fo.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">
<xsl:output encoding="iso-8859-1" />
<xsl:template match ="services">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="service">
<fo:region-body></fo:region-body>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="service">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:table>
<fo:table-body>
<fo:table-row>
<fo:table-cell border="solid 1px black"
text-align="center" font-weight="bold">
<fo:block>Service Id</fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px black"
text-align="center" font-weight="bold">
<fo:block>Open Date</fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px black"
text-align="center" font-weight="bold">
<fo:block>Close Date</fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px black"
text-align="center" font-weight="bold">
<fo:block>Order Status</fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px black"
text-align="center" font-weight="bold">
<fo:block>Description</fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px black"
text-align="center" font-weight="bold">
<fo:block>Repair Cost</fo:block>
</fo:table-cell>
</fo:table-row>
<xsl:for-each select="./service">
<fo:table-row>
<fo:table-cell border="solid 1px bold" text-align="center">
<fo:block><xsl:value-of select="serviceId" /></fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px bold" text-align="center">
<fo:block><xsl:value-of select="openDate" /></fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px bold" text-align="center">
<fo:block><xsl:value-of select="closeDate" /></fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px bold" text-align="center">
<fo:block><xsl:value-of select="orderStatus" /></fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px bold" text-align="center">
<fo:block><xsl:value-of select="description" /></fo:block>
</fo:table-cell>
<fo:table-cell border="solid 1px bold" text-align="center">
<fo:block><xsl:value-of select="repairCost" /></fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
UPDATE
我覺得我得到了它,我需要使用resourceResponse.getPortletOutputStream().write(pdfBytes); resourceResponse.getPortletOutputStream().flush();
而不是resourceResponse.getWriter().print(pdfBytes); resourceResponse.getWriter().flush();