基于ItextSharp的C#电子票单PDF拆分及邮件附件发送需求
修改方案:单票单PDF并批量作为邮件附件发送
核心思路
原代码将所有票页合并为单个PDF,现在需要循环处理每张票的字节流,单独生成独立PDF文档,收集所有生成的内存流后统一作为附件发送。需调整PDF生成逻辑,并修改邮件发送方法以支持多附件。
修改步骤及代码
- 替换原多页PDF生成逻辑,改为循环生成单页PDF并收集内存流:
// 存储所有单票PDF的内存流集合 List<MemoryStream> individualTicketStreams = new List<MemoryStream>(); foreach (var b in PhonepagesAll) { // 为每张票创建独立的内存流和PDF文档 MemoryStream singleTicketStream = new MemoryStream(); Document singleDoc = new Document(); PdfSmartCopy singleCopy = new PdfSmartCopy(singleDoc, singleTicketStream); singleDoc.Open(); // 导入当前票的页面并添加到新PDF singleCopy.AddPage(copy.GetImportedPage(new PdfReader(b), 1)); // 关闭文档但保留内存流(后续需作为附件读取) singleCopy.CloseStream = false; singleCopy.Close(); singleDoc.Close(); // 将流指针重置到起始位置,确保邮件能读取完整内容 singleTicketStream.Position = 0; individualTicketStreams.Add(singleTicketStream); } // 调用修改后的SendTickets方法,传入所有单票PDF流 SendTickets(fullName, emailAddress, individualTicketStreams);
- 修改
SendTickets方法,支持接收多个内存流作为附件:
public void SendTickets(string fullName, string emailAddress, List<MemoryStream> ticketStreams) { // 省略邮件客户端初始化等基础代码,重点处理多附件逻辑 using (var message = new MailMessage("sender@example.com", emailAddress)) { message.Subject = $"您的电子票"; message.Body = $"您好{fullName},附件是您购买的电子票"; // 循环添加每个单票PDF作为独立附件 for (int i = 0; i < ticketStreams.Count; i++) { var attachment = new Attachment(ticketStreams[i], $"电子票_{i+1}.pdf", "application/pdf"); message.Attachments.Add(attachment); } // 发送邮件 using (var smtpClient = new SmtpClient("smtp.example.com")) { smtpClient.Send(message); } } // 发送完成后释放所有内存流资源,避免内存泄漏 foreach (var stream in ticketStreams) { stream.Dispose(); } }
关键注意事项
- 每个单PDF生成后必须重置
MemoryStream.Position为0,否则邮件读取附件会得到空内容 - 关闭
PdfSmartCopy时需设置CloseStream = false,防止内存流被提前关闭 - 邮件发送完成后要手动释放所有
MemoryStream资源
内容的提问来源于stack exchange,提问作者user23224098
相关产品推荐
相关产品推荐

