package com.yiboshi.science.utils; import com.itextpdf.text.pdf.BaseFont; import com.lowagie.text.DocumentException; import freemarker.cache.ClassTemplateLoader; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateExceptionHandler; import org.apache.velocity.app.Velocity; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import org.xhtmlrenderer.pdf.ITextFontResolver; import org.xhtmlrenderer.pdf.ITextRenderer; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.HashMap; import java.util.Map; import static java.lang.System.in; public class PDF { /** * 将HTML模板转换为PDF输出流 * @return PDF字节数组 */ public static byte[] createPDF(HttpServletResponse response,String temp,Object dataModel) throws IOException, TemplateException, DocumentException { Map<String, Object> dataMap = HtmlBuilder.obj2Map(dataModel); // 配置FreeMarker Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); cfg.setDefaultEncoding("utf-8"); cfg.setClassLoaderForTemplateLoading(PDF.class.getClassLoader(), "template"); cfg.setTemplateLoader(new ClassTemplateLoader(PDF.class.getClassLoader(), "/template")); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); // 获取模板 Template template = cfg.getTemplate(temp, "utf-8"); // 处理模板,生成HTML内容 StringWriter tmpText = new StringWriter(); template.process(dataMap, tmpText); String htmlContent = tmpText.toString(); // 创建PDF渲染器 ITextRenderer renderer = new ITextRenderer(); // 设置中文字体 String simPath = ResourceFileUtil.getAbsolutePath("/fonts/simsun.ttc"); String msyhPath = ResourceFileUtil.getAbsolutePath("/fonts/msyh.ttc"); renderer.getFontResolver().addFont(simPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); renderer.getFontResolver().addFont(msyhPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); // 渲染HTML内容 renderer.setDocumentFromString(htmlContent); renderer.layout(); // 创建一个ByteArrayOutputStream来保存生成的PDF response.setContentType("application/octet-stream;charset=UTF-8"); OutputStream outputStream = response.getOutputStream(); // 输出PDF到字节数组 renderer.createPDF(outputStream); //创建存放文件内容的数组 byte[] buff = new byte[1024]; //所读取的内容使用n来接收 int n; //当没有读取完时,继续读取,循环 while ((n = in.read(buff)) != -1) { //将字节数组的数据全部写入到输出流中 outputStream.write(buff, 0, n); } //强制将缓存区的数据进行输出 outputStream.flush(); //关流 outputStream.close(); in.close(); // 关闭输出流 return buff; } public static boolean createPDF(String temp,Object dataModel,String outputPath) throws IOException, TemplateException, DocumentException { Map<String, Object> dataMap = HtmlBuilder.obj2Map(dataModel); // 配置FreeMarker Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); cfg.setDefaultEncoding("utf-8"); cfg.setClassLoaderForTemplateLoading(PDF.class.getClassLoader(), "template"); cfg.setTemplateLoader(new ClassTemplateLoader(PDF.class.getClassLoader(), "/template")); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); // 获取模板 Template template = cfg.getTemplate(temp, "utf-8"); // 处理模板,生成HTML内容 StringWriter tmpText = new StringWriter(); template.process(dataMap, tmpText); String htmlContent = tmpText.toString(); // 创建PDF渲染器 ITextRenderer renderer = new ITextRenderer(); // 设置中文字体 String simPath = ResourceFileUtil.getAbsolutePath("/fonts/simsun.ttc"); String msyhPath = ResourceFileUtil.getAbsolutePath("/fonts/msyh.ttc"); renderer.getFontResolver().addFont(simPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); renderer.getFontResolver().addFont(msyhPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); // 渲染HTML内容 renderer.setDocumentFromString(htmlContent); renderer.layout(); // 创建输出文件 File outputFile = new File(outputPath); // 确保父目录存在 outputFile.getParentFile().mkdirs(); // 创建文件输出流 try (OutputStream outputStream = new FileOutputStream(outputFile)) { // 输出PDF到文件 renderer.createPDF(outputStream); outputStream.flush(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } }