在此,首先感谢
这篇链接的博主,无私奉献他的力量
感谢互联网的无私和真诚
我借助此文完成了我的需求,下载pdf简历 ,所以在此记录一笔
项目的大概功能如下 vue的页面点击下载按钮就能下载简历 ,谷歌浏览器
浏览器中点开这个简历如下这样的, 里面还有打印和下载
一 首先你需要引入如下 pom依赖
org.springframework.boot
spring-boot-starter-freemarker
org.xhtmlrenderer
flying-saucer-pdf
9.1.12
二 工具类
接着 工具类 : 实在强大 ,可根据自身业务修改
package com.ruoyi.common.util;
import com.lowagie.text.pdf.baseFont;
import com.platform.domain.ProcessJobresumeinfo;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.w3c.dom.document;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.documentBuilder;
import javax.xml.parsers.documentBuilderFactory;
import java.io.*;
public class PdfUtils {
private PdfUtils() {
}
private static final Logger LOGGER = LoggerFactory.getLogger(PdfUtils.class);
private static document generateDoc(FreeMarkerConfigurer configurer, String templateName, ProcessJobresumeinfo variables) {
Template tp;
try {
tp = configurer.getConfiguration().getTemplate(templateName);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
return null;
}
StringWriter stringWriter = new StringWriter();
try(BufferedWriter writer = new BufferedWriter(stringWriter)) {
try {
tp.process(variables, writer);
writer.flush();
} catch (TemplateException e) {
LOGGER.error("模板不存在或者路径错误", e);
} catch (IOException e) {
LOGGER.error("IO异常", e);
}
documentBuilder builder = documentBuilderFactory.newInstance().newdocumentBuilder();
return builder.parse(new ByteArrayInputStream(stringWriter.toString().getBytes()));
}catch (Exception e){
LOGGER.error(e.getMessage(), e);
return null;
}
}
private static void generateAll(FreeMarkerConfigurer configurer, String templateName, OutputStream out,ProcessJobresumeinfo info) throws Exception {
if (info==null) {
LOGGER.warn("警告:简历模板参数为空!");
return;
}
ITextRenderer renderer = new ITextRenderer();
document doc = generateDoc(configurer, templateName, info);
renderer.setdocument(doc, null);
//设置字符集(宋体),此处必须与模板中的一致,区分大小写,不能写成汉字"宋体"
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont("simsun.ttc", baseFont.IDENTITY_H, baseFont.NOT_EMBEDDED);
//展现和输出pdf
renderer.layout();
renderer.createPDF(out, false);
renderer.finishPDF(); //完成pdf写入
}
public static void download(FreeMarkerConfigurer configurer, String templateName, ProcessJobresumeinfo info, HttpServletResponse response, String fileName) {
// 设置编码、文件ContentType类型、文件头、下载文件名
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
try {
response.setHeader("Content-Disposition", "attachment;fileName=" +
new String(fileName.getBytes("gb2312"), "ISO8859-1"));
} catch (UnsupportedEncodingException e) {
LOGGER.error(e.getMessage(), e);
}
try (ServletOutputStream out = response.getOutputStream()) {
generateAll(configurer, templateName, out, info);
out.flush();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
public static void preview(FreeMarkerConfigurer configurer, String templateName, ProcessJobresumeinfo info, HttpServletResponse response) {
try (ServletOutputStream out = response.getOutputStream()) {
generateAll(configurer, templateName, out, info);
out.flush();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
}
注意 这里有三个东西,resources下的templates加入pdfResume.ftl模板 (自己加) , 还有一个simsun.ttc字体,这个说是window系统有,但是我系统并没有,可以百度搜索下载资源,这里不做分享
flt模板
${name}简历信息
@page {
size: 210mm 297mm;
margin: 0.25in;
padding: 1em;
@bottom-center {
content: "xxx 版权所有";
font-family: SimSun;
font-size: 12px;
color: red;
};
@top-center {
content: element(header)
};
@bottom-right {
content: "第" counter(page) "页 共 " counter(pages) "页";
font-family: SimSun;
font-size: 12px;
color: #000;
};
}
个人简历
<#if birthday??>
#if>
<#if phone??>
#if>
<#if weixin??>
#if>
<#if advantage??>
#if>
求职期望
<#if hopes?exists>
<#list hopes as hope>
求职期望 ${hope_index+1}
<#if hope.jobtype??>
#if>
<#if hope.jobcity??>
#if>
<#if hope.jobtype??>
#if>
<#if hope.job??>
#if>
#list>
#if>
工作经历
<#if workExpers?exists>
<#list workExpers as we>
工作经历 ${we_index+1}
<#if we.cname??>
#if>
<#if we.business??>
#if>
<#if we.addtime??>
#if>
<#if we.endtime??>
#if>
<#if we.jobtitle??>
#if>
<#if we.department??>
#if>
<#if we.jobcontent??>
#if>
#list>
#if>
项目经验
<#if projectExps?exists>
<#list projectExps as pj>
项目 ${pj_index+1}
<#if pj.projectname??>
#if>
<#if pj.role??>
#if>
<#if pj.projectstarttime??>
#if>
<#if pj.projectendtime??>
#if>
<#if pj.projectinfo??>
#if>
#list>
#if>
教育经历
<#if educations?exists>
<#list educations as ed>
教育经历 ${ed_index+1}
<#if ed.schoolname??>
#if>
<#if ed.education??>
#if>
<#if ed.profession??>
#if>
<#if ed.estart??>
#if>
<#if ed.schoolexperience??>
#if>
#list>
#if>
<#if certificate??>
#if>
三 web框架自行引入
controller info是简历信息 ,查询数据库那一些操作这里不分享了
@RequestMapping(value = "/preview", method = RequestMethod.GET)
public void preview(HttpServletRequest request, HttpServletResponse response) {
String id = request.getParameter("id");
Jobresumeinfo info = infoService.selectinfoById(id);
PdfUtils.preview(configurer,"pdfResume.ftl",info,response);
}
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void download(HttpServletRequest request, HttpServletResponse response) {
String id = request.getParameter("id");
Jobresumeinfo info = infoService.selectinfoById(id);
PdfUtils.download(configurer,"pdfResume.ftl",info,response,"简历信息");
}
vue部分
html
下载
查看
填工时
婉拒
通过
js
downPDF(row){
var pdfname = row.name + "-"+row.phone;
downPDF(row).then(response => {
console.log(this.pdfUrl)
const elink = document.createElement("a");
elink.href = window.URL.createObjectURL(new Blob([response], {type: `application/pdf`}));
elink.style.display = 'none';
elink.setAttribute('download', pdfname);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
});



