使用Apache PDFBox将含3个表格的Grid类转PDF并邮件发送的实现方案
基于Apache PDFBox实现Grid表格转PDF并邮件发送的解决方案
一、修正后的Maven依赖
确保PDFBox及邮件发送的依赖配置正确,建议使用较新版本的PDFBox以规避已知问题:
<!-- Apache PDFBox 核心依赖 --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.32</version> </dependency> <!-- JavaMail 依赖(用于邮件发送) --> <dependency> <groupId>com.sun.mail</groupId> <artifactId>jakarta.mail</artifactId> <version>2.0.1</version> </dependency>
二、Grid表格转PDF核心实现
假设你的Grid类包含getTables()方法,返回3个表格的集合,每个表格包含行、列及单元格数据。以下是完整的PDF生成代码:
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; // 模拟你的Grid及Table、Cell类结构,需替换为实际业务类 class Grid { public List<Table> getTables() { // 返回你的3个表格数据集合 return null; } } class Table { public List<List<String>> getRows() { // 返回表格行数据,每行是单元格字符串集合 return null; } } public class GridToPdfGenerator { // 基础排版配置:可根据需求调整 private static final float START_X = 50; private static final float START_Y = 750; private static final float CELL_WIDTH = 150; private static final float CELL_HEIGHT = 20; private static final float FONT_SIZE = 12; public static ByteArrayOutputStream generatePdfFromGrid(Grid grid) throws IOException { try (PDDocument doc = new PDDocument()) { PDPage page = new PDPage(); doc.addPage(page); try (PDPageContentStream contentStream = new PDPageContentStream(doc, page)) { contentStream.setFont(PDType1Font.HELVETICA, FONT_SIZE); float currentY = START_Y; // 遍历Grid中的3个表格 for (Table table : grid.getTables()) { List<List<String>> rows = table.getRows(); if (rows == null || rows.isEmpty()) continue; // 绘制表格边框与单元格内容 for (int rowIdx = 0; rowIdx < rows.size(); rowIdx++) { List<String> cells = rows.get(rowIdx); float currentX = START_X; for (String cellText : cells) { // 绘制单元格边框 contentStream.addRect(currentX, currentY - CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT); contentStream.stroke(); // 填充单元格文本 contentStream.beginText(); contentStream.newLineAtOffset(currentX + 5, currentY - CELL_HEIGHT + 5); contentStream.showText(cellText != null ? cellText : ""); contentStream.endText(); currentX += CELL_WIDTH; } currentY -= CELL_HEIGHT; // 页面空间不足时自动分页 if (currentY < 50) { contentStream.close(); page = new PDPage(); doc.addPage(page); contentStream = new PDPageContentStream(doc, page); contentStream.setFont(PDType1Font.HELVETICA, FONT_SIZE); currentY = START_Y; } } // 表格间留空行分隔 currentY -= 10; } } // 将PDF写入内存流,用于邮件附件 ByteArrayOutputStream baos = new ByteArrayOutputStream(); doc.save(baos); return baos; } } }
三、邮件发送实现(含PDF附件)
将生成的PDF作为附件发送邮件,示例代码如下:
import jakarta.mail.*; import jakarta.mail.internet.InternetAddress; import jakarta.mail.internet.MimeBodyPart; import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMultipart; import java.io.ByteArrayOutputStream; import java.util.Properties; public class EmailSender { public static void sendPdfEmail(ByteArrayOutputStream pdfStream, String toAddress, String subject, String content) throws MessagingException { // 邮件服务器配置(以QQ邮箱为例,需替换为你的服务商信息) Properties props = new Properties(); props.put("mail.smtp.host", "smtp.qq.com"); props.put("mail.smtp.port", "587"); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); // 发件人账号信息,需替换为实际账号 String fromAddress = "your-email@qq.com"; String password = "your-app-specific-password"; Session session = Session.getInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(fromAddress, password); } }); // 构建邮件消息 Message message = new MimeMessage(session); message.setFrom(new InternetAddress(fromAddress)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toAddress)); message.setSubject(subject); // 邮件正文 MimeBodyPart textPart = new MimeBodyPart(); textPart.setText(content); // PDF附件 MimeBodyPart pdfPart = new MimeBodyPart(); pdfPart.setFileName("grid-tables.pdf"); pdfPart.setContent(pdfStream.toByteArray(), "application/pdf"); // 组合邮件内容 Multipart multipart = new MimeMultipart(); multipart.addBodyPart(textPart); multipart.addBodyPart(pdfPart); message.setContent(multipart); // 发送邮件 Transport.send(message); } }
四、整合调用示例
将PDF生成与邮件发送逻辑整合,完成完整流程:
public class Main { public static void main(String[] args) { try { // 初始化你的Grid实例,填充3个表格数据 Grid grid = new Grid(); // 生成PDF内存流 ByteArrayOutputStream pdfStream = GridToPdfGenerator.generatePdfFromGrid(grid); // 发送邮件 EmailSender.sendPdfEmail( pdfStream, "recipient@example.com", "Grid表格PDF附件", "您好,附件为Grid中的3个表格PDF文件,请查收。" ); System.out.println("PDF生成及邮件发送完成"); } catch (Exception e) { e.printStackTrace(); } } }
关键注意事项
- 需根据实际的
Grid、Table类结构,调整GridToPdfGenerator中获取表格数据的逻辑。 - 邮件服务器配置需对应你使用的邮箱服务商(如网易、Gmail等),注意开启SMTP服务并使用授权码而非登录密码。
- 若表格内容较多,可进一步优化分页逻辑,支持更复杂的单元格内容(如换行、不同宽度)。
内容的提问来源于stack exchange,提问作者Vishu Dhanawade
相关产品推荐
相关产品推荐

