import com.itextpdf.text.pdf.BaseFont;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.xhtmlrenderer.pdf.ITextRenderer;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Map;
public class PDFUtils {
private static String DEFAULT_ENCODING="utf-8";
private static String PDF_TYPE="application/pdf";
private static boolean DEFAULT_NOCACHE=true;
private static String HEADER_ENCODING="utf-8";
private static String HEADER_NOCACHE="no-cache";
/**
* 生成PDF文件流
* @param ftlName 文件名称
* @param data 数据
* @return ByteArrayOutputStream
* @throws Exception
*/
public static void createPDF(String ftlName, Map<String,Object> data, HttpServletResponse response) throws Exception {
// 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例
Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
// 指定FreeMarker模板文件的位置
cfg.setClassForTemplateLoading(PDFUtils.class,"/templates");
ITextRenderer renderer = new ITextRenderer();
try {
// 设置 css中 的字体样式(暂时仅支持宋体和黑体) 必须,不然中文不显示
renderer.getFontResolver().addFont("/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.getFontResolver().addFont("/宋体-粗体.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
// 设置模板的编码格式
cfg.setEncoding(Locale.CHINA, "UTF-8");
// 获取模板文件
Template template = cfg.getTemplate(ftlName+".ftl", "UTF-8");
StringWriter writer = new StringWriter();
// 将数据输出到html中
template.process(data, writer);
writer.flush();
String html = writer.toString();
// 把html代码传入渲染器中
renderer.setDocumentFromString(html);
// 解决图片的相对路径问题 ##必须在设置document后再设置图片路径,不然不起作用
renderer.getSharedContext().setBaseURL("images/");
renderer.layout();
//生成PDF
ByteArrayOutputStream baos = new ByteArrayOutputStream();
renderer.createPDF(baos);
baos.close();
renderPdf(response, baos.toByteArray(), ftlName);
} catch(Exception e) {
throw new Exception(e);
}
}
public static void renderPdf(HttpServletResponse response, final byte[] bytes, final String filename) {
response = initResponseHeader(response, PDF_TYPE);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
String now3 = df.format(System.currentTimeMillis());
setFileDownloadHeader(response, filename+now3, ".pdf");
if (null != bytes) {
try {
response.getOutputStream().write(bytes);
response.getOutputStream().flush();
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
}
/**
* 分析并设置contentType与headers.
*/
private static HttpServletResponse initResponseHeader(HttpServletResponse response, final String contentType, final String... headers) {
// 分析headers参数
String encoding = DEFAULT_ENCODING;
boolean noCache = DEFAULT_NOCACHE;
for (String header : headers) {
String headerName = StringUtils.substringBefore(header, ":");
String headerValue = StringUtils.substringAfter(header, ":");
if (StringUtils.equalsIgnoreCase(headerName, HEADER_ENCODING)) {
encoding = headerValue;
} else if (StringUtils.equalsIgnoreCase(headerName, HEADER_NOCACHE)) {
noCache = Boolean.parseBoolean(headerValue);
} else {
throw new IllegalArgumentException(headerName + "不是一个合法的header类型");
}
}
// 设置headers参数
String fullContentType = contentType + ";charset=" + encoding;
response.setContentType(fullContentType);
if (noCache) {
// Http 1.0 header
response.setDateHeader("Expires", 0);
response.addHeader("Pragma", "no-cache");
// Http 1.1 header
response.setHeader("Cache-Control", "no-cache");
}
return response;
}
/**
* 设置让浏览器弹出下载对话框的Header.
* @param
*/
public static void setFileDownloadHeader(HttpServletResponse response, String fileName, String fileType) {
try {
// // 中文文件名支持
String encodedfileName = new String(fileName.getBytes("GBK"), "ISO8859-1");
//弹出下载pdf
// response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedfileName + fileType + "\"");
//预览pdf
response.setHeader("Content-Disposition", "inline;filename="
+ encodedfileName + fileType);
} catch (UnsupportedEncodingException e) {
}
// response.setHeader("Content-Disposition", "attachment; filename="+fileName+fileType);
}
}
pdf工具类
最新推荐文章于 2024-06-24 09:42:16 发布