首次使用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中 的字体样式(暂时仅支持宋体和黑体) 必须,不然中文不显示
// 使用类加载器获取资源文件InputStream
InputStream 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