Apache FOP — PDF-файл передается во вложение электронной почты Commons

Я использую Apache Fop с XSL-FO для создания PDF. Затем я пытаюсь передать pdf в виде вложения в apache.commons.mail.HtmlEmail; Я получаю электронные письма с вложением, однако получаю следующую ошибку. Длина 0 байт, кодировка отсутствует. Я могу создать pdf файл в файловой системе без каких-либо проблем, поэтому я знаю, что в части FOP этого кода нет ничего плохого, поэтому я не совсем уверен, почему он не работает. Может ли кто-нибудь сказать мне, что мне не хватает?

Мой код.

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());
    }
}

фоп-класс

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);
    }
}

}


person Code Junkie    schedule 17.08.2012    source источник
comment
Почти уверен, что application/pdf не ваша проблема. Я сам использовал то же самое при передаче PDF-файлов.   -  person BlackVegetable    schedule 17.08.2012
comment
#BlackVegetable Я добавил свой класс франтов, возможно, вы сможете заметить что-то, что я упускаю.   -  person Code Junkie    schedule 17.08.2012
comment
На самом деле я работал с SugarCRM в этом случае. Из-за того, как настроен их API, мне требуется сохранить файл на диск (локально), а затем обратиться к этому файловому объекту для передачи. Я знаю, что это не прямой ответ на ваш вопрос, но вы можете захотеть сохранить файл локально, попытаться отправить его и, если отправка прошла успешно, удалить файл локально. Я не могу с первого взгляда найти что-то не так с вашим кодом FOP. Поскольку вы можете создать документ в своей файловой системе, я сомневаюсь, что ваша проблема тоже существует.   -  person BlackVegetable    schedule 17.08.2012
comment
да, это не звучит идеально.   -  person Code Junkie    schedule 17.08.2012


Ответы (1)


вы перезаписываете outStream в generatePDF(), поэтому тот, который вы передаете, остается пустым. Удалите эту строку и повторите попытку.

outStream = new ByteArrayOutputStream();
person centic    schedule 17.08.2012