前提:有html文件,且里面有该有的数据
目标:生成PDF文件
步骤:
1.打造html模版,并构造好文件的存放路径
/**
* 获取模版的创建路径
* @return 年/月/日
*/
@Override
@Transactional(readOnly = true)
public String buildHtmlOutFilePath(){
Date date = new Date();
return PathEnum.TEMPLATE_HTML.getPath()
+ DateUtil.year(date)
+ "/"
+ DateUtil.month(date)
+ "/"
+ DateUtil.dayOfMonth(date)
+ "/"
+ UUID.randomUUID().toString()
+ ".html";
}
/**
* 获取pdf的创建路径
* @return 年/月/日/年/月/日/uuid.pdf
*/
@Override
@Transactional(readOnly = true)
public String buildPdfOutFilePath(){
Date date = new Date();
return PathEnum.TEMPLATE_PDF.getPath()
+ DateUtil.year(date)
+ "/"
+ DateUtil.month(date)
+ "/"
+ DateUtil.dayOfMonth(date)
+ "/"
+ UUID.randomUUID().toString()
+ ".pdf";
}
2.用data和html生成html静态文件
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.UUID;
/**
* 生成静态文件
* @param freeTempName 模板名称
* @param context 数据内容
* @param outFilePath 输出路径
* @return true:创建成功,false:创建失败
*/
@Override
@Transactional(readOnly = true)
public boolean processAndCreateHtml(String freeTempName, Context context, String outFilePath) {
FileWriter fileWriter = null;
try {
File file = new File(outFilePath);
File parent = file.getParentFile();
// 如果pdf保存路径不存在,则创建路径
if (!parent.exists()) {
parent.mkdirs();
}
fileWriter = new FileWriter(outFilePath);
templateEngine.process(freeTempName, context,fileWriter);
} catch (Exception e) {
log.error(e.getMessage(),e);
return false;
} finally {
try {
if (fileWriter != null){
fileWriter.close();
}
} catch (IOException e) {
log.error(e.getMessage(),e);
return false;
}
}
return true;
}
3.html生成PDF文件
// wkhtmltopdf在系统中的路径
private final static String toPdfTool = "/usr/local/bin/wkhtmltopdf";
/**
* html转pdf
*
* @param srcPath html路径,可以是硬盘上的路径,也可以是网络路径
* @param destPath pdf保存路径
* @return 转换成功返回true
*/
public static boolean convert(String srcPath, String destPath, String cmdStr) {
File file = new File(destPath);
File parent = file.getParentFile();
// 如果pdf保存路径不存在,则创建路径
if (!parent.exists()) {
parent.mkdirs();
}
StringBuilder cmd = new StringBuilder();
cmd.append(toPdfTool);
cmd.append(" ");
cmd.append(cmdStr);
// cmd.append(" -O landscape --javascript-delay 8000 --print-media-type --margin-top 30mm --page-width 500mm --page-height 6500mm --disable-smart-shrinking ");
cmd.append(srcPath);
cmd.append(" ");
cmd.append(destPath);
boolean result = true;
try {
Process proc = Runtime.getRuntime().exec(cmd.toString());
HtmlToPdfInterceptor error = new HtmlToPdfInterceptor(proc.getErrorStream());
HtmlToPdfInterceptor output = new HtmlToPdfInterceptor(proc.getInputStream());
error.start();
output.start();
proc.waitFor();
} catch (Exception e) {
result = false;
log.error(e.getMessage(), e);
}
return result;
}
4.处理2、3逻辑关系
@Override
@Transactional(readOnly = true)
public String html2Pdf(String freeTempName, Context context) {
String htmlOutFilePath = buildHtmlOutFilePath();
boolean createHtml = processAndCreateHtml(freeTempName, context, htmlOutFilePath);
if (!createHtml){
throw new BaseException(PayrollExceptionCode.DATA_NOT_FOUND);
}
String pdfOutFilePath = buildPdfOutFilePath();
boolean convert = WKHtmlToPdfUtil.convert(htmlOutFilePath, pdfOutFilePath, " ");
if (!convert){
throw new BaseException(PayrollExceptionCode.DATA_NOT_FOUND);
}
return pdfOutFilePath;
}
5.service层处理
Context context = new Context();
context.setVariable("payslipInfos", payslipEmployeeInfoBos);
String filePath = thymeleafService.html2Pdf("payslipPdfTemplate", context);
6.下载到本地。或者。上传附件发送邮箱
下载到本地:
AssertUtil.notNull(payslipEmployeeInfos, PayrollExceptionCode.DATA_NOT_FOUND);
List<PayslipEmployeeInfoBo> payslipEmployeeInfoBos = buildPayslipEmployeeInfoBos(payslipEmployeeInfos);
//数据处理
Context context = new Context();
context.setVariable("payslipInfos", payslipEmployeeInfoBos);
String filePath = thymeleafService.html2Pdf("payslipPdfTemplate", context);
try {
File file = new File(filePath);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", URLEncoder.encode(getPayslipInfoName(payslipEmployeeInfoBos), "utf-8"));
return new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
} catch (IOException e) {
log.error(e.getMessage(), e);
throw new BaseException(PayrollExceptionCode.DATA_NOT_FOUND);
}
发送邮箱:
数据处理+发送+日志处理
public void getProvider(CommonEmailMessage commonEmailMessage, String template, JavaMailSenderImpl javaMailSender, List<MultipartFile> multipartFileList, List<String> employeeNumbers) throws MessagingException, IOException, BindingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
//判断file数组不能为空并且长度大于0
for (MultipartFile file : multipartFileList) {
//保存文件
if (!file.isEmpty()) {
mimeMessageHelper.addAttachment(file.getOriginalFilename(), file, file.getContentType());
}
}
if (commonEmailMessage.getFromName() != null) {
mimeMessageHelper.setFrom(commonEmailMessage.getFrom(),commonEmailMessage.getFromName());
}else {
mimeMessageHelper.setFrom(commonEmailMessage.getFrom());
}
List<EmailAddress> to = commonEmailMessage.getTo();
List<InternetAddress> list=new ArrayList<>();
for (EmailAddress emailAddress : to) {
InternetAddress internetAddress = new InternetAddress();
internetAddress.setAddress(emailAddress.getAddress());
internetAddress.setPersonal(emailAddress.getPersonal());
list.add(internetAddress);
}
InternetAddress[] internetAddresses = list.toArray(new InternetAddress[0]);
mimeMessageHelper.setTo(internetAddresses);
mimeMessageHelper.setSubject(commonEmailMessage.getSubject());
mimeMessageHelper.setText(template,true);
if(commonEmailMessage.getCc()!=null&&!commonEmailMessage.getCc().isEmpty()){
List<InternetAddress> list1=new ArrayList<>();
List<EmailAddress> cc = commonEmailMessage.getCc();
for (EmailAddress emailAddress : cc) {
InternetAddress internetAddress = new InternetAddress();
internetAddress.setAddress(emailAddress.getAddress());
internetAddress.setPersonal(emailAddress.getPersonal());
list1.add(internetAddress);
}
InternetAddress[] internetAddresses1 = list1.toArray(new InternetAddress[0]);
mimeMessageHelper.setCc(internetAddresses1);
}
emailServiceProvider.send(mimeMessage, javaMailSender, commonEmailMessage, template, multipartFileList, employeeNumbers);
}
javaMailSender.send(mimeMessage);
public class EmailSendMessage {
@ApiModelProperty("发件人名称")
private String fromName;
@ApiModelProperty("发件人账号id")
private Integer accountId;
@ApiModelProperty("收件人邮箱地址[数组] 二选一")
private List<EmailAddress> to;
@ApiModelProperty("抄送人邮箱地址[cc]")
private List<EmailAddress> cc;
@ApiModelProperty(value = "员工工号数组 二选一")
private String employeeNumbers;
@ApiModelProperty(value = "主题")
private String subject;
@ApiModelProperty(value = "模板code")
private String code;
@ApiModelProperty(value = "邮件模板参数映射")
private Map<String, Object> paramMap;
@ApiModelProperty(value = "邮件模板内容(传了内容不用传code)")
private String specialBody;
@ApiModelProperty(value = "附件")
MultipartFile[] multipartFile;
}
7.相关文件
public class CommonEmailMessage {
private EmailServiceConfig emailServiceConfig;
private String from;
private String fromName;
private List<EmailAddress> to;
private List<EmailAddress> cc;
private String subject;
private String code;
private Map<String, Object> paramMap;
private Integer isRetry;
private Integer retryLogId;
}
@Data
public class PayslipEmployeeInfoBo {
private Integer id;
//关联的工资单id
private Integer payslipInfoId;
//员工id
private Integer employeeId;
//员工编号
private String employeeNumber;
//员工名称
private String employeeName;
//部门名称
private String departmentName;
//岗位名称
private String stationName;
//是否可见
private Boolean isVisible;
//人员头像
private String imageUrl;
//备注
private String remark;
//实发
private BigDecimal actualValue;
//表头分组
private List<PayslipEmployeeInfoGroupBo> tableHeader;
//分组详情
private List<PayslipEmployeeInfoGroupBo> groups;
}
html+thymeleaf