Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send e-mail in Pdf attachment as stream

I want to send a Pdf as an e-mail attachment (I am using the JavaMail API ). I have the Pdf (generated by jasper) as an 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);
    }

Here is the code that I am using to construct the MimeBodyPart that will be the attachment:

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

This code gives me this error:

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="
like image 680
Atticus Avatar asked Jan 27 '11 13:01

Atticus


People also ask

How do I send a PDF as a stream?

Go to your stream's Write page and click on the upload icon, located at the top-right corner of the content editor. 2. Click on the Choose File button to select the PDF file from your computer that you wish to upload into your stream. Your file will begin uploading into your stream.

How do I send a PDF as an email not an attachment?

Open the PDF file in the Adobe Acrobat Reader. Click on “Edit” from the menu along the top and select “Copy File to Clipboard.” Open the email you want to send and paste the file by holding down the "Control" key and then “V,” or right-click and select “Paste” from the menu.


2 Answers

I have found a solution as suggested in this thread. It seems that there is a DataSource class created just for this purpose. Hope this example will help others also.

    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);
    }
like image 92
Atticus Avatar answered Sep 27 '22 22:09

Atticus


The constructor you used is for parsing a mime part from the transport.

Your second example should work out right. You may consider

  • not to convert to InputStream and back, this will make unnecessary copies
  • add a disposition ( e.g. bp.setDisposition(Part.ATTACHMENT); )
like image 35
mtraut Avatar answered Sep 27 '22 20:09

mtraut