- 创建springboot项目,pom文件引入依赖如下:3
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> <version>2.3.12.RELEASE</version> </dependency> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.0.9</version> </dependency>
3.创建工具类2个:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Encoder;
import java.io.File;
import java.io.FileInputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class CommunalTool {
/**
* 转换数据中的null为""(空串)
*
* @param obj 转换之前的数据
* @param beanClass 转换之后的数据类型
* @return 返回Object
* @throws Exception
*/
public static Object objectToData(Object obj, Class<?> beanClass) throws Exception {
return JSONObject.parseObject(objectToString(obj), beanClass);
}
/**
* Map中的null转换成""(空串)
*
* @param map 转换之前的数据
* @return 返回 Map<String,Object>
* @throws Exception
*/
public static Map<String, Object> objectToMap(Map<String, Object> map) throws Exception {
return JSONObject.parseObject(objectToString(map), Map.class);
}
/**
* 把list中的null转换成""(空串)
*
* @param list 转换之前的数据
* @return 返回list
* @throws Exception
*/
public static List objectToList(List list) throws Exception {
return JSONObject.parseObject(objectToString(list), List.class);
}
// fistJson 的一个过滤器
static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
static DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
private static ValueFilter filter = new ValueFilter() {
@Override
public Object process(Object obj, String s, Object v) {
if (v instanceof Date) {
return simpleDateFormat.format(v);
} else {
if (v == null) {
return "";
} else {
return v;
}
}
}
};
/**
* 将对象转换为json格式的字符串
*
* @param obj
* @return String
*/
public static String objectToString(Object obj) {
// JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd";
return JSON.toJSONString(obj, filter, SerializerFeature.WriteNonStringKeyAsString, SerializerFeature.WriteNullStringAsEmpty);
}
/**
* 将图片转成base64 字符串
*
* @param path 文件路径
* @return
* @throws Exception
*/
public static String encodeBase64Picture(String path) throws Exception {
File file = new File(path);
FileInputStream inputFile = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
inputFile.read(buffer);
inputFile.close();
String result = new BASE64Encoder().encode(buffer);
if (StringUtils.isNotBlank(result)) {
result = "data:image/png;base64," + result;
} else {
result = null;
}
return result;
}
/**
* 时间转换 yyyy-MM-dd
*
* @param date
* @return
*/
public static String getTransformationDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
/**
* 时间转换 yyyy-MM-dd
*
* @param date
* @return
*/
public static String getTimeDate(Date date) {
int minte = getMinute(date);
minte = minte % 5;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Date afterDate = new Date(date.getTime() + 300000);
System.out.println(sdf.format(afterDate));
return "1";
}
/**
* 功能描述:返回分
*
* @param date
* 日期
* @return 返回分钟
*/
public static int getMinute(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.MINUTE);
}
/**
* 获取日期年份
* @param date 日期
* @return
*/
public static String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
public static String getTime(Date date) {
SimpleDateFormat df = new SimpleDateFormat(FORMAT_FULL);
return df.format(date).substring(12, 16);
}
}
import com.lowagie.text.pdf.BaseFont;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Map;
@Component
public class PdfHelper {
/**
* classpath路径
*/
private String classpath = getClass().getResource("/").getPath();
/**
* 指定FreeMarker模板文件的位置
*/
private String templatePath = "/templates";
/**
* freeMarker模板文件名称
*/
private String templateFileName = "test.ftl";
/**
* 字体资源文件 存放路径
*/
private String fontPath = "font/";
/**
* 字体 [宋体][simsun.ttc] [黑体][simhei.ttf]
*/
private String font = "simsun.ttc";
/**
* 指定编码
*/
private String encoding = "UTF-8";
/**
* 生成pdf
*
* @param data 传入到freemarker模板里的数据
* @param out 生成的pdf文件流
*/
public void createPDF(Map<String, Object> data, OutputStream out, String templateName) throws Exception {
// 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例
Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
// 指定FreeMarker模板文件的位置
ITextRenderer renderer = new ITextRenderer();
/**
* 要修改为字体下的路径
*/
String simsun = System.getProperty("user.dir") + "\\src\\main\\resources\\font\\simsun.ttc";
File fondFile = new File(simsun);
if (!fondFile.exists()) {
getFondPath();
}
renderer.getFontResolver().addFont(simsun, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
StringTemplateLoader stringLoader = new StringTemplateLoader();
String templateString = getFileData("templates/" + templateName);
stringLoader.putTemplate("myTemplate", templateString);
cfg.setTemplateLoader(stringLoader);
Template tpl = cfg.getTemplate("myTemplate", "utf-8");
StringWriter writer = new StringWriter();
// 把null转换成""
Map<String, Object> dataMap = CommunalTool.objectToMap(data);
// 将数据输出到html中
tpl.process(data, writer);
writer.flush();
String html = writer.toString();
// 把html代码传入渲染器中
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(out, false);
renderer.finishPDF();
out.flush();
out.close();
}
// 读取jar中的ftl模版文件
private String getFileData(String path) {
InputStream stream = getClass().getClassLoader().getResourceAsStream(path);
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
String s = null;
while ((s = br.readLine()) != null) {
sb.append(s);
}
br.close();
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (br != null) {
try {
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 获取字体路径
*
* @return
* @throws IOException
*/
private String getFondPath() throws IOException {
String fontPath = System.getProperty("user.dir");
/**
* 要修改为字体下路径
*/
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("font/simsun.ttc");
//在根目录生成一个文件
File targetFile = new File(fontPath + "/simsun.ttc");
// //将流转成File格式
FileUtils.copyInputStreamToFile(inputStream, targetFile);
return fontPath;
}
public void setClasspath(String classpath) {
this.classpath = classpath;
}
public void setTemplatePath(String templatePath) {
this.templatePath = templatePath;
}
public void setTemplateFileName(String templateFileName) {
this.templateFileName = templateFileName;
}
public void setFontPath(String fontPath) {
this.fontPath = fontPath;
}
public void setFont(String font) {
this.font = font;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
}
准备html文件修改后缀名为ftl文件
在controller下调用API测试生成接口pdf文档
//生成pdf流
@PostMapping("/export")
public void export(HttpServletResponse response,HttpServletRequest request) throws Exception {
ServletOutputStream out = null;
String userId = JwtUtils.parseToken(request.getHeader("token"));
User user=userService.getById(Long.parseLong(userId));
PdfHelper pdfHelper = new PdfHelper();
Map<String,Object> map = new HashMap<>();
map.put("name",user.getUserName());
FileOutputStream outFile = new FileOutputStream(new File( "D:\\manager\\src\\main\\resources\\pdf\\"+user.getUserName()+"成绩证明"+".pdf"));
pdfHelper.createPDF(map,outFile,"test.ftl");
// try{
// out = response.getOutputStream();
//
// /** 导出pdf文件流 */
// response.setCharacterEncoding("UTF-8");
// response.setContentType("application/pdf");
// response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline; filename="+ URLEncoder.encode("测试","UTF-8"));
//
// FileInputStream inputStream = new FileInputStream(new File( "D:\\manager\\src\\main\\resources\\pdf\\1.pdf"));
// // 读取文件流
// int len = 0;
// byte[] buffer = new byte[1024 * 10];
// while ((len = inputStream.read(buffer)) != -1) {
// out.write(buffer, 0, len);
// }
// out.close();
// }catch (Exception e){
// e.printStackTrace();
// }
}