2012-12-04 40 views
0

我正在嘗試生成一個pdf下載文件。我有以下代碼來生成pdf從xmlxsl-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();

回答