【问题标题】:Send e-mail in Pdf attachment as stream以流的形式发送 Pdf 附件中的电子邮件
【发布时间】:2011-06-16 13:38:51
【问题描述】:

我想将 Pdf 作为电子邮件附件发送(我正在使用 JavaMail API)。我有 Pdf(由 jasper 生成)作为byte[]

public InputStream exportPdfToInputStream(User user) throws ParseErrorException, MethodInvocationException, ResourceNotFoundException, JRException, IOException{
        JasperPrint jasperPrint = createJasperPrintObject(user);
        byte[] pdfByteArray = JasperExportManager.exportReportToPdf(jasperPrint);
        return new ByteArrayInputStream(pdfByteArray);
    }

这是我用来构造MimeBodyPart 的代码,它将成为附件:

    if (arrayInputStream != null && arrayInputStream instanceof ByteArrayInputStream) {
        MimeBodyPart attachment = new MimeBodyPart(arrayInputStream);
        attachment.setHeader("Content-Type", "application/pdf");
        mimeMultipart.addBodyPart(attachment);
    }

这段代码给了我这个错误:

javax.mail.MessagingException: IOException while sending message;
  nested exception is:
    java.io.IOException: Error in encoded stream: needed at least 2 valid base64 characters, but only got 1 before padding character (=), the 10 most recent characters were: "\24\163\193\n\185\194\216#\208="

【问题讨论】:

    标签: java email jakarta-mail mime-types


    【解决方案1】:

    我找到了this 线程中建议的解决方案。似乎为此目的创建了一个DataSource 类。希望这个例子也能对其他人有所帮助。

        if (arrayInputStream != null && arrayInputStream instanceof ByteArrayInputStream) {
            // create the second message part with the attachment from a OutputStrean
            MimeBodyPart attachment= new MimeBodyPart();
            ByteArrayDataSource ds = new ByteArrayDataSource(arrayInputStream, "application/pdf"); 
            attachment.setDataHandler(new DataHandler(ds));
            attachment.setFileName("Report.pdf");
            mimeMultipart.addBodyPart(attachment);
        }
    

    【讨论】:

    • 这将完全读取 InputStream 并且字节数组完全存储在 ByteArrayDataSource 中。因此,对于大型附件,您的内存使用率会很高。对吧?
    【解决方案2】:

    您使用的构造函数用于解析传输中的 mime 部分。

    你的第二个例子应该是正确的。你可以考虑

    • 不要转换为 InputStream 并返回,这会产生不必要的副本
    • 添加处置(例如 bp.setDisposition(Part.ATTACHMENT);

    【讨论】:

    • @mtraut:您说不要将其转换为 InputStream 并返回,但是如果没有 InputStream 怎么办?
    • 使用 ByteArrayDataSource(byte[] data, String type) 构造函数和“pdfByteArray”
    • @mtraut:谢谢,这就是我在回答中已经提交的内容。不过还是谢谢。我虽然有另一种更简单的方法来做到这一点!
    • @Atticus - 不完全是。在您的回答中,您使用了 INputStream 构造函数,这会导致另一个副本...
    • 使用“处置”,您可以尝试控制客户处理零件的方式。虽然所有类型的实现都不能正确地遵守这一点,但“附件”肯定会导致预期的行为。虽然 PDF 附件的风险很小,但如果声明不正确,“text/html”或“text/plain”附件可能会在电子邮件中内联呈现。认为它的风格很好......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    • 2014-02-28
    • 1970-01-01
    相关资源
    最近更新 更多