首次使用freemarker遇到的全是坑,还好,各种问题,最终都解决了。芹菜加油
import com.lowagie.text.pdf.BaseFont;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xhtmlrenderer.pdf.ITextRenderer;import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;public class PDFUtils {private static Log logger = LogFactory.getLog(PDFUtils.class);public static ByteArrayOutputStream createPDFFromHtml(String html) throws Exception {ITextRenderer renderer = new ITextRenderer();OutputStream out = new ByteArrayOutputStream();logger.info("getFontResolver********************************************************start");// 设置 css中 的字体样式(暂时仅支持宋体和黑体) 必须,不然中文不显示// 使用类加载器获取资源文件InputStreamInputStream fontInputStream = PDFUtils.class.getResourceAsStream("/font/simsun.ttf");if (fontInputStream == null) {throw new RuntimeException("Font file not found in classpath.");}// 将资源文件临时复制到系统临时目录,以便iText访问Path tempFontFile = Files.createTempFile("simsun", ".ttf");Files.copy(fontInputStream, tempFontFile, StandardCopyOption.REPLACE_EXISTING);fontInputStream.close();String ss= tempFontFile.toString();// 添加临时字体文件到字体解析器,使用linux发版,同时需要将字体放到linux服务器中,renderer.getFontResolver().addFont(ss, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
// 如果使用windows发版,使用下面方式,
// renderer.getFontResolver().addFont("/usr/share/fonts/simsunsongti.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);// 把html代码传入渲染器中logger.info("setDocumentFromString********************************************************start");renderer.setDocumentFromString(html);logger.info("setDocumentFromString********************************************************end");renderer.layout();renderer.createPDF(out, false);renderer.finishPDF();logger.info("finishPDF********************************************************end");out.flush();ByteArrayOutputStream byteArrayOutputStream = (ByteArrayOutputStream) out;return byteArrayOutputStream;}
}
//图片 测试环境:netUrl: https://test.net.com.cn@Value("${netUrl}")private String netUrl;//图片地址 :/api/file/sys-file/@Value("${fileUrl}")private String fileUrl;/*** 从模板文件中加载* @param response* @throws Exception*/@PostMapping("/template/file")public void load(HttpServletResponse response, @RequestBody ParmObjDto parmObjDto) throws Exception {R r = ticketService.getByRecordId(parmObjDto.getRecordId());WkElectricalTicketVo apply = JSONUtil.toBean(JSONUtil.toJsonStr(r.getData()), WkElectricalTicketVo.class);String templateFileName = "/one.ftl";List<Map<String,Object>> list = new ArrayList<>();Map<String,Object> map = new HashMap();map.put("recordId", apply.getRecordId());map.put("deptCode", apply.getWorkUnit());map.put("deptName", apply.getDeptName());map.put("workOrderName", apply.getWorkOrderName());map.put("operationTicketNumber", apply.getOperationTicketNumber());map.put("workTicketNumber", apply.getWorkTicketNumber());map.put("unitType", apply.getUnitType());//放图片的话,模板上出不来,需要如下设置map.put("workObject", apply.getWorkObject());// 图片if(StringUtils.isNotEmpty(apply.getIssuerSign())) {map.put("issuerSign",StringEscapeUtils.escapeXml10(netUrl + fileUrl + apply.getIssuerSign()));}else{map.put("issuerSign","");}//计划开始时间,处理日期,防止为空,必须,否则如果为空,模板显示会报错Date date1 = apply.getTimeStart();Optional<Date> optionalDate = Optional.ofNullable(date1);if (optionalDate.isPresent()) {String t