2012-08-17 94 views
1

我使用Apache Fop和XSL-FO來生成PDF。然後,我嘗試將pdf作爲附件傳輸到apache.commons.mail.HtmlEmail;我收到附件的電子郵件,但是我收到以下錯誤。長度爲0字節,編碼無。我可以在文件系統上創建一個pdf,沒有任何問題,所以我知道這段代碼的FOP部分沒有問題,所以我不確定它爲什麼不起作用。有人能告訴我我錯過了什麼嗎?Apache FOP - PDF流式傳輸到Commons Email Attachment

我的代碼。

private void sendBroadcastNofications(PurchaseRequest pr) { 
    try { 
     ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
     //Fop sevice used to generate pdf. 
     this.xmlPDFGeneratorService.generatePDF(pr, outputStream); 
     byte[] bytes = outputStream.toByteArray(); 

     //I'm not sure if "application/pdf" would be an issue since fop is giving 
     //it the MimeConstants.MIME_PDF 
     DataSource source = new ByteArrayDataSource(bytes, "application/pdf");    
     EmailAttachment attachment = new EmailAttachment(source, "purchase_requisition.pdf", "Broadcast Purcahse Requisition"); 

     Util.email("Purchase Request " + pr.getPrNumber(), getGenerateMessage(pr), pr.getAuthorizer().getEmail(), attachment); 

    } catch (IOException ex) { 
     Logger.getLogger(EmailServiceImpl.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 


public static void email(String subject, String message, String recipient, EmailAttachment attachment) { 
    email(subject, message, Collections.singleton(recipient), Collections.singleton(attachment)); 
} 

public static void email(String subject, String message, Set<String> recipients, Set<EmailAttachment> attachments) { 
    try { 
     HtmlEmail email = new HtmlEmail(); 

     email.setHostName("mailhost"); 
     email.setSubject(subject); 
     email.setHtmlMsg(message); 
     email.setFrom("[email protected]"); 

     for (EmailAttachment attachment : attachments) { 
      try { 
       email.attach(attachment.getDataSource(), attachment.getName(), attachment.getDescription()); 
      } catch (EmailException ex) { 
       System.err.println("Email Attachment Exception: " + ex.getMessage()); 
      } 
     } 

     for (String recipient : recipients) { 
      email.addTo(recipient); 
     } 
     email.send(); 
    } catch (EmailException ex) { 
     System.err.println("Email Failed to Send: " + ex.getMessage()); 
    } 
} 

Fop的類

public class XMLPDFGeneratorServiceImpl implements XMLPDFGeneratorService { 

private static final File baseDir = new File("."); 
private static final File xsltfile = new File(baseDir, "./PurchaseRequestPDF.xsl"); 

// configure fopFactory as desired 
private final FopFactory fopFactory = FopFactory.newInstance(); 

public void generatePDF(PurchaseRequest pr, ByteArrayOutputStream outStream) { 

    // configure foUserAgent as desired 
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); 

    try { 

     // Setup output 
     outStream = new ByteArrayOutputStream(); 

     // Construct fop with desired output format 
     Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, outStream); 

     // Setup XSLT 
     TransformerFactory factory = TransformerFactory.newInstance(); 
     Transformer transformer = factory.newTransformer(new StreamSource(xsltfile)); 

     // Set the value of a <param> in the stylesheet 
     transformer.setParameter("versionParam", "2.0"); 

     ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
     generateXML(pr, stream); 

     byte[] out = stream.toByteArray(); 
     stream.close(); 

     ByteArrayInputStream in = new ByteArrayInputStream(out); 
     // Setup input for XSLT transformation 
     Source src = new StreamSource(in); 

     // Resulting SAX events (the generated FO) must be piped through to FOP 
     Result res = new SAXResult(fop.getDefaultHandler()); 

     // Start XSLT transformation and FOP processing 
     transformer.transform(src, res); 

    } catch (TransformerException ex) { 
     Logger.getLogger(XMLPDFGeneratorServiceImpl.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IOException ex) { 
     Logger.getLogger(XMLPDFGeneratorServiceImpl.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (FOPException ex) { 
     Logger.getLogger(XMLPDFGeneratorServiceImpl.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

public void generateXML(PurchaseRequest pr, ByteArrayOutputStream stream) { 
    try { 
     // create JAXB context and instantiate marshaller 
     JAXBContext context = JAXBContext.newInstance(PurchaseRequest.class); 
     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
     m.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE); 
     m.marshal(pr, new PrintWriter(stream)); 
    } catch (JAXBException ex) { 
     Logger.getLogger(XMLPDFGeneratorServiceImpl.class.getName()).log(Level.SEVERE, "JAXB Failed to produce xml stream", ex); 
    } 
} 

}

+0

很確定'application/pdf' *不是*您的問題。我自己在傳輸PDF文件時使用了相同的功能。 – BlackVegetable 2012-08-17 16:38:24

+0

#BlackVegetable我加了我的fop課,也許你可以發現我可能會丟失的東西。 – 2012-08-17 17:24:04

+0

在這種情況下,我實際上一直在使用SugarCRM。由於其API設置的方式,它需要我將文件保存到磁盤(本地),然後引用該文件對象進行傳輸。我知道這不是直接回答您的問題,但您可能需要考慮在本地保存文件,嘗試發送文件,並且如果發送成功,請在本地刪除文件。我一眼就找不到你的FOP代碼有什麼問題。因爲您可以在文件系統上創建文檔,所以我懷疑您的問題是否存在。 – BlackVegetable 2012-08-17 17:36:50

回答

3

要覆蓋在generatePDF的outStream(),因此你通過在一個保持爲空。刪除該行並重試。

outStream = new ByteArrayOutputStream(); 
+0

很好的解決了我的問題。謝謝Centic – 2012-08-20 17:46:09