简单介绍一下:如何将html文件转化为pdf文件。
最近开发项目中使用到了iText富文本框,遇到的问题就是如何将后台库里保存的HTML内容转换成PDF,网上找了好多方法,大多数都是读取本地已存在的HTML文件,然后再转换成pdf,项目需求是读取数据库保存的HTML,然后以PDF的形式导出到本地,这边介绍下我的实现方式。
代码实现
package com.nisco.dms.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.sql.Clob;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.layout.font.FontProvider;
import com.nisco.dms.service.DcWhiteListService;
import com.nisco.dms.service.NoticeService;
import com.nisco.dms.util.ClobTrsUtil;
import com.nisco.dms.util.ControllerUtil;
import com.nisco.dms.util.dwz.AjaxObject;
import com.nisco.dms.util.dwz.Page;
/**
*
* @ClassName: ItextController
* @Description: TODO(iText)
* @author wjt
* @date 2019年1月31日
*
*/
@Controller
@RequestMapping(value = "/itext")
public class ItextController {
@Resource
private DcWhiteListService dcWhiteListService;
@Autowired
private NoticeService noticeService;
public static final String TARGET = "F:/target/results/ch01/";
public static final String BASEURI = "/mc/styles/AdminLTE-2.4.2/bower_components/summernote-0.8.11-dist";
@RequestMapping(value = "/htmltopdf",method = RequestMethod.POST)
@ResponseBody
public String htmlToPdf(String id,HttpServletResponse response,HttpServletRequest request){
AjaxObject ajaxObject = new AjaxObject();
ajaxObject.setMessage("");
try {
//先从后台读取HTML信息,这边只是保存的部门,不是一个完整的HTML
Map<String,Object> map = noticeService.findOneById(id);
//由于前台传过来的HTML数据量大,所以数据库是用Clob类型保存,这边做了个转化
String content = ClobTrsUtil.ClobToString((Clob)(map.get("content")));
OutputStream out = response.getOutputStream();
File file = new File(TARGET);
file.mkdirs();
//转换之前需要设置一些属性信息,比如HTML用到的css样式和js都要引入
ConverterProperties properties = new ConverterProperties();
FontProvider font = new FontProvider();
font.addStandardPdfFonts();
//获取中文字体文件路径,这里讲下,iText不支持中文转换,也就是说如果不引入中文字体文件,导出的PDF不显示中文,网上说的最多的是用simsun.ttc这个中文支持文件,我这边试了下,没有效果,我用的是windows10的SIMYOU.TTF,这个在c盘下可以找到,可以把他复制到项目中去
String appPath = request.getSession().getServletContext().getRealPath("/mc/styles/AdminLTE-2.4.2/bower_components/summernote-0.8.11-dist/SIMYOU.TTF");
// 设置你的字体文件
font.addFont(appPath);
properties.setFontProvider(font);
properties.setBaseUri(BASEURI);
//转换,content存的是HTML
HtmlConverter.convertToPdf(content, new FileOutputStream("F:/target/results/ch01/stest-01.pdf"),properties);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ajaxObject.toString();
}
}
//clob类型转string,Clob类型的对象通常要转换成String类型
/**
*
* @Title: ClobToString
* @Description: TODO(将Clob类型的数据转换为String类型)
* @param @param clob
* @param @return
* @param @throws Exception 参数
* @return String 返回类型
* @throws
*/
public static String ClobToString(Clob clob) throws Exception{
String ret = "";
Reader read= clob.getCharacterStream();
BufferedReader br = new BufferedReader(read);
String s = br.readLine();
StringBuffer sb = new StringBuffer();
while (s != null) {
sb.append(s);
s = br.readLine();
}
ret = sb.toString();
if(br != null){
br.close();
}
if(read != null){
read.close();
}
return ret;
}
总结:这种方法适用于将后台传过来的HTML字段(部分)转换成PDF文件输出到本地,在使用过程中主要遇到的问题就是中文不显示,字体样式缺失,解决方法就是引入中文支持文件,和iText自带的summermote.css文件。
刚入门的菜鸟,有写的不对的地方请大佬们指出,有好的方法请大佬们给建议,感激不尽!欢迎大家来交流