
1.邮箱参数
@Configuration
@Data
public class EmailUtils {
@Value("${email.from}")
private String from;
@Value("${email.fromKey}")
private String fromKey;
@Value("${email.fromHost}")
private String fromHost;
@Value("${email.fromPort}")
private String fromPort;
}
2.发送邮件
String fromEmail, smtpHost, smtpPort, authCode;
fromEmail = emailUtils.getFrom();
authCode = emailUtils.getFromKey();
smtpHost = emailUtils.getFromHost();
smtpPort = emailUtils.getFromPort();
// 生成 PDF
PDFGenerator pdfGenerator = new PDFGenerator();
List<String[]> businessData = new ArrayList<>();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
LocalDateTime lastSaturdayStart = now.minusDays(7)
.withHour(0)
.withMinute(0)
.withSecond(0);
// 计算前1天(本周五)的23:59:59
LocalDateTime thisFridayEnd = now.minusDays(1)
.withHour(23)
.withMinute(59)
.withSecond(59);
// 输出结果
String startTime = lastSaturdayStart.format(formatter);
String endTime = thisFridayEnd.format(formatter);
// 假设的业务数据
List<String[]> clientData = new ArrayList<>();
List<SysDept> deptList = deptMapper.selectSubsidiaryList();
for (SysDept sysDept : deptList) {
List<Long> userList = wechatUserMapper.selectSubsidiaryUserId(sysDept.getDeptId());
if (userList.size() == 0) {
clientData.add(new String[]{sysDept.getDeptName(), "0", "0", "0", "0"});
businessData.add(new String[]{sysDept.getDeptName(), "0", "0", "0", "0"});
continue;
}
//客户、实验校
ClientWeekVO clientWeek = clientMapper.selectWeekInfo(userList, startTime, endTime);
ClientWeekVO schoolWeek = schoolMapper.selectWeekInfo(userList, startTime, endTime);
List<Long> clientList = clientMapper.selectClientUser(userList);
clientData.add(new String[]{sysDept.getDeptName(), clientWeek.getAllCount(), clientWeek.getWeekCount(), schoolWeek.getAllCount(), schoolWeek.getWeekCount()});
if (clientList.size() == 0) {
businessData.add(new String[]{sysDept.getDeptName(), "0", "0", "0", "0"});
continue;
}
//回款、订单
ClientWeekVO returnedWeek = returnedMapper.selectWeekInfo(clientList, startTime, endTime);
if (!Objects.isNull(returnedWeek)) {
if (returnedWeek.getWeekCount() == null) {
returnedWeek.setWeekCount("0");
}
if (returnedWeek.getAllCount() == null) {
returnedWeek.setAllCount("0");
}
}
if (Objects.isNull(returnedWeek)) {
returnedWeek = new ClientWeekVO();
returnedWeek.setWeekCount("0");
returnedWeek.setAllCount("0");
}
ClientWeekVO orderWeek = ordersMapper.selectWeekInfo(clientList, startTime, endTime);
if (!Objects.isNull(orderWeek)) {
if (orderWeek.getWeekCount() == null) {
orderWeek.setWeekCount("0");
}
if (orderWeek.getAllCount() == null) {
orderWeek.setAllCount("0");
}
}
if (Objects.isNull(orderWeek)) {
orderWeek = new ClientWeekVO();
orderWeek.setWeekCount("0");
orderWeek.setAllCount("0");
}
businessData.add(new String[]{sysDept.getDeptName(), orderWeek.getAllCount(), orderWeek.getWeekCount(), returnedWeek.getAllCount(), returnedWeek.getWeekCount()});
}
String pdfPath = pdfGenerator.generateBusinessReport(businessData, clientData, startTime, endTime);
String subject = "业务周报";
// 设置多个收件人
LambdaQueryWrapper<Email> wrapper = new LambdaQueryWrapper<>();
List<Email> emailLists = emailMapper.selectList(wrapper);
List<String> emailList = new ArrayList<>();
for (Email email : emailLists) {
emailList.add(email.getEmailAddress());
}
// 配置邮件服务器属性
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
// 获取会话对象
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(fromEmail, authCode);
}
});
try {
// 创建邮件消息
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromEmail));
message.setSubject(subject);
try {
InternetAddress[] recipientAddresses = emailList.stream()
.map(email -> {
try {
return new InternetAddress(email);
} catch (AddressException e) {
System.out.println("无效的邮箱地址: " + email);
return null;
}
})
.filter(Objects::nonNull)
.toArray(InternetAddress[]::new);
message.setRecipients(Message.RecipientType.TO, recipientAddresses);
} catch (Exception e) {
System.out.println("设置收件人失败: " + e.getMessage());
return;
}
// 创建邮件内容部分
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("请查收附件中的经营周报!");
// 创建附件部分
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(pdfPath);
// 将文本和附件组合成多重消息
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(textPart);
multipart.addBodyPart(attachmentPart);
// 设置邮件内容
message.setContent(multipart);
// 发送邮件
Transport.send(message);
System.out.println("邮件发送成功,附件已附加!");
} catch (MessagingException |
IOException e) {
e.printStackTrace();
System.out.println("邮件发送失败!");
}
}
3.生成PDF
package com.ruoyi.quartz.util.email;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.TextAlignment;
import java.io.FileOutputStream;
import java.util.List;
/**
* 业务数据和客户数据 PDF 生成器
*
* @author laoyou
*/
public class PDFGenerator {
public String generateBusinessReport(List<String[]> businessData, List<String[]> clientData, String startTime, String endTime) {
String pdfPath = "业务周报.pdf";
try (PdfWriter writer = new PdfWriter(new FileOutputStream(pdfPath));
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc)) {
// 加载中文字体
//PdfFont font = PdfFontFactory.createFont("C:\\Windows\\Fonts\\simsun.ttc,1", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
PdfFont font = PdfFontFactory.createFont("/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc,0", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
document.setFont(font);
// 添加报告标题
document.add(new Paragraph("业务周报").setFont(font).setBold().setFontSize(18).setTextAlignment(TextAlignment.CENTER));
// 添加时间区间
document.add(new Paragraph("数据时间: " + startTime + " 至 " + endTime).setFont(font).setFontSize(12).setTextAlignment(TextAlignment.CENTER));
// 添加业务情况标题
document.add(new Paragraph("本周各区业务情况").setFont(font).setBold().setFontSize(16).setTextAlignment(TextAlignment.CENTER));
// 业务数据表格
document.add(new Paragraph("业务数据").setFont(font).setBold().setFontSize(14).setTextAlignment(TextAlignment.CENTER));
Table businessTable = new Table(new float[]{2, 2, 2, 2, 2});
businessTable.setHorizontalAlignment(HorizontalAlignment.CENTER);
String[] businessHeaders = {
"子公司/大区",
"订单 总金额",
"订单 上周增加额",
"回款 总金额",
"回款 上周增加额"
};
for (String header : businessHeaders) {
businessTable.addCell(new Cell().add(new Paragraph(header).setFont(font).setBold().setTextAlignment(TextAlignment.CENTER)));
}
for (String[] row : businessData) {
for (String cellData : row) {
businessTable.addCell(new Cell().add(new Paragraph(cellData).setFont(font).setTextAlignment(TextAlignment.CENTER)));
}
}
document.add(businessTable);
// 客户数据表格
document.add(new Paragraph("客户数据").setFont(font).setBold().setFontSize(14).setTextAlignment(TextAlignment.CENTER));
Table clientTable = new Table(new float[]{2, 2, 2, 2, 2});
clientTable.setHorizontalAlignment(HorizontalAlignment.CENTER);
String[] clientHeaders = {
"子公司/大区",
"客户 总数量",
"客户 上周增加数",
"实验校 总数量",
"实验校 上周增加数"
};
for (String header : clientHeaders) {
clientTable.addCell(new Cell().add(new Paragraph(header).setFont(font).setBold().setTextAlignment(TextAlignment.CENTER)));
}
for (String[] row : clientData) {
for (String cellData : row) {
clientTable.addCell(new Cell().add(new Paragraph(cellData).setFont(font).setTextAlignment(TextAlignment.CENTER)));
}
}
document.add(clientTable);
} catch (Exception e) {
e.printStackTrace();
System.out.println("PDF 生成失败!");
}
return pdfPath;
}
}
4.示例
