java如何合并itextpdf和java邮件?
java How to combine itextpdf and java mail?
嘿,我正在开发一个 Web 应用程序,但我在结合 2 个功能时遇到了问题(构建一个 pdf 并将其作为附件通过电子邮件发送)。这两个部分是分开工作的,但我不知道如何获取创建的 PDF 的文件路径以将其添加到邮件附件中。
以下为重要代码片段:
- 我使用 java servlet CreatePDF 创建一个新的 PDF 文件(itext 5)并在新选项卡中显示它:
创建 PDF Servlet:
//initial new ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//get absolute path of the logo
String relativeLogoWebPath = "/logo.jpg";
String absoluteLogoDiskPath = getServletContext().getRealPath(relativeLogoWebPath);
//build PDF with itextpdf
new BuildPDF(baos, acc, absoluteLogoDiskPath, header, body, footer, vat);
// setting the content type
response.setHeader("Expires", "0");
response.setHeader("Cache-Control","must-revalidate, post-check=0,precheck=0");
response.setHeader("Pragma", "public");
response.setContentType("application/pdf");
response.setContentLength(baos.size());
// write ByteArrayOutputStream to the ServletOutputStream
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
BuildPDF Class:
public BuildPDF(ByteArrayOutputStream baos, Accounting acc, String absolutLogoPath,
Collection<String> header, Collection<String> body, Collection<String> footer, Double vat){
//init document
Document document = new Document(PageSize.A4, 60, 30, 140, 90);
document.setMarginMirroring(false);
//init pdf writer
PdfWriter writer = PdfWriter.getInstance(document, baos);
writer.setBoxSize("art", new com.itextpdf.text.Rectangle(36, 54, 559, 788));
//add header and footer
HeaderFooter event = new HeaderFooter(header, footer, absolutLogoPath);
writer.setPageEvent(event);
//open the document
document.open();
//add title and body
addTitle(document, acc)
addBody(document, acc, body, vat, writer);
//close document and pdf writer
document.close();
writer.close();
}
- 在另一个选项卡中,我转到下一个 jsp 页面,单击按钮(打开 servlet SendAccouningPage)后,应该可以通过电子邮件发送此已创建的 pdf(使用 java 邮件):
SendAccountingPage Servlet:
//TODO: get path of created PDF
String[] attachFiles = new String[1];
//attachFiles[0] = (String) request.getSession().getAttribute("pdfPath");
//request.getSession().removeAttribute("pdfPath");
EmailUtility.sendEmailWithAttachments(host, port, fromMail, passwort,
mail, subject, message, attachFiles);
电子邮件实用程序Class:
public static void sendEmailWithAttachments(String host, String port,
final String userName, final String password, String toAddress,
String subject, String message, String[] attachFiles)
throws AddressException, MessagingException {
// sets SMTP server properties
Properties properties = new Properties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.user", userName);
properties.put("mail.password", password);
// creates a new session with an authenticator
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
};
Session session = Session.getInstance(properties, auth);
// creates a new e-mail message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(userName));
InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
msg.setRecipients(Message.RecipientType.TO, toAddresses);
msg.setSubject(subject);
msg.setSentDate(new Date());
// creates message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(message, "text/html");
// creates multi-part
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// adds attachments
if (attachFiles != null && attachFiles.length > 0) {
for (String filePath : attachFiles) {
MimeBodyPart attachPart = new MimeBodyPart();
try {
attachPart.attachFile(filePath);
} catch (IOException ex) {
ex.printStackTrace();
}
multipart.addBodyPart(attachPart);
}
}
// sets the multi-part as e-mail's content
msg.setContent(multipart);
// sends the e-mail
Transport.send(msg);
}
那么有没有办法获取创建的 pdf 的文件路径并将其存储,例如进入session? (如果是的话:这条路的抵抗力如何?如果我用创建的 pdf 关闭选项卡,它会丢失吗?)
如果没有:
不然怎么组合呢?
我是否必须保存 pdf(如果是:我必须保存哪些机会,是否可以仅临时保存它?)
您正在使用 ByteArrayOutputStream
(名为 baos
)在内存中创建 PDF,然后将此文件写入 servlet 的输出流:
OutputStream os = response.getOutputStream();
baos.writeTo(os);
这是一种很好的做法,但还有一种替代方法。
ByteArrayOutputStream
有一个名为 toByteArray()
的方法,所以你也可以这样做:
OutputStream os = response.getOutputStream();
byte[] bytes = baos.toByteArray();
os.write(bytes, 0, bytes.length);
os.flush();
os.close();
现在您在 byte[]
中有了名为 bytes
的完整文件,您需要调整 EmailUtility
class 以便它接受字节数组而不是文件的路径。在对以下问题的回答中对此进行了解释:Mail Attachments with byte array:
MimeBodyPart att = new MimeBodyPart();
ByteArrayDataSource bds = new ByteArrayDataSource(byte, "application/pdf");
att.setDataHandler(new DataHandler(bds));
att.setFileName(bds.getName());
这就是您发送带有文件附件的邮件的方式,该文件是在内存中创建的,从未作为文件存储在服务器的磁盘上。
嘿,我正在开发一个 Web 应用程序,但我在结合 2 个功能时遇到了问题(构建一个 pdf 并将其作为附件通过电子邮件发送)。这两个部分是分开工作的,但我不知道如何获取创建的 PDF 的文件路径以将其添加到邮件附件中。
以下为重要代码片段:
- 我使用 java servlet CreatePDF 创建一个新的 PDF 文件(itext 5)并在新选项卡中显示它:
创建 PDF Servlet:
//initial new ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//get absolute path of the logo
String relativeLogoWebPath = "/logo.jpg";
String absoluteLogoDiskPath = getServletContext().getRealPath(relativeLogoWebPath);
//build PDF with itextpdf
new BuildPDF(baos, acc, absoluteLogoDiskPath, header, body, footer, vat);
// setting the content type
response.setHeader("Expires", "0");
response.setHeader("Cache-Control","must-revalidate, post-check=0,precheck=0");
response.setHeader("Pragma", "public");
response.setContentType("application/pdf");
response.setContentLength(baos.size());
// write ByteArrayOutputStream to the ServletOutputStream
OutputStream os = response.getOutputStream();
baos.writeTo(os);
os.flush();
os.close();
BuildPDF Class:
public BuildPDF(ByteArrayOutputStream baos, Accounting acc, String absolutLogoPath,
Collection<String> header, Collection<String> body, Collection<String> footer, Double vat){
//init document
Document document = new Document(PageSize.A4, 60, 30, 140, 90);
document.setMarginMirroring(false);
//init pdf writer
PdfWriter writer = PdfWriter.getInstance(document, baos);
writer.setBoxSize("art", new com.itextpdf.text.Rectangle(36, 54, 559, 788));
//add header and footer
HeaderFooter event = new HeaderFooter(header, footer, absolutLogoPath);
writer.setPageEvent(event);
//open the document
document.open();
//add title and body
addTitle(document, acc)
addBody(document, acc, body, vat, writer);
//close document and pdf writer
document.close();
writer.close();
}
- 在另一个选项卡中,我转到下一个 jsp 页面,单击按钮(打开 servlet SendAccouningPage)后,应该可以通过电子邮件发送此已创建的 pdf(使用 java 邮件):
SendAccountingPage Servlet:
//TODO: get path of created PDF
String[] attachFiles = new String[1];
//attachFiles[0] = (String) request.getSession().getAttribute("pdfPath");
//request.getSession().removeAttribute("pdfPath");
EmailUtility.sendEmailWithAttachments(host, port, fromMail, passwort,
mail, subject, message, attachFiles);
电子邮件实用程序Class:
public static void sendEmailWithAttachments(String host, String port,
final String userName, final String password, String toAddress,
String subject, String message, String[] attachFiles)
throws AddressException, MessagingException {
// sets SMTP server properties
Properties properties = new Properties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.user", userName);
properties.put("mail.password", password);
// creates a new session with an authenticator
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
};
Session session = Session.getInstance(properties, auth);
// creates a new e-mail message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(userName));
InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
msg.setRecipients(Message.RecipientType.TO, toAddresses);
msg.setSubject(subject);
msg.setSentDate(new Date());
// creates message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(message, "text/html");
// creates multi-part
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
// adds attachments
if (attachFiles != null && attachFiles.length > 0) {
for (String filePath : attachFiles) {
MimeBodyPart attachPart = new MimeBodyPart();
try {
attachPart.attachFile(filePath);
} catch (IOException ex) {
ex.printStackTrace();
}
multipart.addBodyPart(attachPart);
}
}
// sets the multi-part as e-mail's content
msg.setContent(multipart);
// sends the e-mail
Transport.send(msg);
}
那么有没有办法获取创建的 pdf 的文件路径并将其存储,例如进入session? (如果是的话:这条路的抵抗力如何?如果我用创建的 pdf 关闭选项卡,它会丢失吗?)
如果没有:
不然怎么组合呢?
我是否必须保存 pdf(如果是:我必须保存哪些机会,是否可以仅临时保存它?)
您正在使用 ByteArrayOutputStream
(名为 baos
)在内存中创建 PDF,然后将此文件写入 servlet 的输出流:
OutputStream os = response.getOutputStream();
baos.writeTo(os);
这是一种很好的做法,但还有一种替代方法。
ByteArrayOutputStream
有一个名为 toByteArray()
的方法,所以你也可以这样做:
OutputStream os = response.getOutputStream();
byte[] bytes = baos.toByteArray();
os.write(bytes, 0, bytes.length);
os.flush();
os.close();
现在您在 byte[]
中有了名为 bytes
的完整文件,您需要调整 EmailUtility
class 以便它接受字节数组而不是文件的路径。在对以下问题的回答中对此进行了解释:Mail Attachments with byte array:
MimeBodyPart att = new MimeBodyPart();
ByteArrayDataSource bds = new ByteArrayDataSource(byte, "application/pdf");
att.setDataHandler(new DataHandler(bds));
att.setFileName(bds.getName());
这就是您发送带有文件附件的邮件的方式,该文件是在内存中创建的,从未作为文件存储在服务器的磁盘上。