import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
/**
* <p>
* Title: PdfUtils.java
* </p>
* <p>
* Description: PDF生成工具类
* </p>
* <p>
* Company:
* </p>
*
* @author huxuewei
* @version v1.0
*/
@SuppressWarnings("all")
public class PDFUtil {
/**
* <p>
* Description: 生成PDF到文件
* </p>
* <p>
* Company:
* </p>
*
* @author ZY
* @param ftlPath
* 模板文件路径(不含文件名)
* @param ftlName
* 模板文件(不含路径)
* @param imageDiskPath
* 图片的磁盘路径
* @param data
* 数据 (填到模板上的数据)
* @param outputFile
* 目标文件(全路径名称)
* @throws Exception
*/
public static void generateToFile(String ftlPath, String ftlName, String imageDiskPath, Object data,
String outputFile) throws Exception {
OutputStream out = null;
ITextRenderer render = null;
try {
String html = getPdfContent(ftlPath, ftlName, data); // 组装模板和数据生成html串
out = new FileOutputStream(outputFile);
render = getRender();
render.setDocumentFromString(html); // 此处抛异常
if (imageDiskPath != null && !imageDiskPath.equals("")) {
// html中如果有图片,图片的路径则使用这里设置的路径的相对路径,这个是作为根路径
render.getSharedContext().setBaseURL("file:/" + imageDiskPath);
}
render.layout();
render.createPDF(out);
render.finishPDF();
render = null;
} catch (Exception e) {
throw e;
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
throw e;
}
}
}
}
/**
* 生成PDF到输出流中(ServletOutputStream用于下载PDF)
*
* @param ftlPath
* ftl模板文件的路径(不含文件名)
* @param ftlName
* ftl模板文件的名称(不含路径)
* @param imageDiskPath
* 如果PDF中要求图片,那么需要传入图片所在位置的磁盘路径
* @param data
* 输入到FTL中的数据
* @param response
* HttpServletResponse
* @return
* @throws TemplateNotFoundException
* @throws MalformedTemplateNameException
* @throws ParseException
* @throws IOException
* @throws TemplateException
* @throws DocumentException
*/
public static ITextRenderer getRender() throws DocumentException, IOException {
ITextRenderer render = new ITextRenderer();
String path = getPath();
// 添加字体,以支持中文
render.getFontResolver().addFont(path + "fonts/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
render.getFontResolver().addFont(path + "fonts/SIMSUN.TTC", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
return render;
}
// 获取要写入PDF的内容
public static String getPdfContent(String ftlPath, String ftlName, Object o) throws Exception {
return useTemplate(ftlPath, ftlName, o);
}
// 使用freemarker得到html内容
public static String useTemplate(String ftlPath, String ftlName, Object o) throws Exception {
String html = null;
Template tpl = getFreemarkerConfig(ftlPath).getTemplate(ftlName);
tpl.setEncoding("UTF-8");
StringWriter writer = new StringWriter();
tpl.process(o, writer);
writer.flush();
html = writer.toString();
return html;
}
/**
* 获取Freemarker配置
*
* @param templatePath
* @return
* @throws IOException
*/
private static Configuration getFreemarkerConfig(String templatePath) throws IOException {
Configuration config = new Configuration();
config.setDirectoryForTemplateLoading(new File(templatePath));
config.setEncoding(Locale.CHINA, "utf-8");
return config;
}
/**
* 获取类项目根路径
*
* @return
*/
public static String getPath() {
// return PDFUtil.class.getResource("").getPath().substring(1);
// //返回类路径(当前类所在的路径)
return PDFUtil.class.getResource("/").getPath().substring(1); // 返回项目根路径(编译之后的根路径)
}
public static void main(String[] args) throws Exception {
String templateName = "off_cnpc_plasthetics";// 需要选用的模板名称
String targetPathRoot = "E:/temp/";// 生成pdf的目标位置
Map<String, Object> map = generateUnitOpenAccountApplicationData();// 构建模板所需数据
try {
String path = PDFUtil.getPath();
// System.out.println(path); //项目根路径
PDFUtil.generateToFile(path, "templates/" + templateName + ".ftl", path + "/images/", map,
targetPathRoot + templateName + ".pdf");
System.out.println("生成PDF成功!");
// 要输出的pdf文件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("E:/temp/abc2.pdf")));
Calendar cal = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
// 将pdf文件先加水印然后输出
setWatermark(bos, "E:/temp/off_cnpc_plasthetics.pdf", format.format(cal.getTime()) + " 下载使用人:" + "测试user",
16);
System.out.println("盖章成功!");
} catch (Exception e) {
e.printStackTrace();
System.out.println("生成PDF失败!");
}
}
public static void setWatermark(BufferedOutputStream bos, String input, String waterMarkName, int permission)
throws DocumentException, IOException {
String path = PDFUtil.getPath();
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, bos);
int total = reader.getNumberOfPages() + 1;
PdfContentByte content;
BaseFont base = BaseFont.createFont(path + "fonts/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
PdfGState gs = new PdfGState();
for (int i = 1; i < total; i++) {
content = stamper.getOverContent(i);// 在内容上方加水印
//content = stamper.getUnderContent(i);//在内容下方加水印
gs.setFillOpacity(0.2f);
// content.setGState(gs);
content.beginText();
content.setColorFill(Color.LIGHT_GRAY);
content.setFontAndSize(base, 50);
content.setTextMatrix(70, 200);
content.showTextAligned(Element.ALIGN_CENTER, "公司内部文件,请注意保密!", 300, 350, 55);
content.setColorFill(Color.BLACK);
content.setFontAndSize(base, 8);
content.showTextAligned(Element.ALIGN_CENTER, "下载时间:" + waterMarkName + "", 300, 10, 0);
content.endText();
}
stamper.close();
}
public static Map<String, Object> generateUnitOpenAccountApplicationData() {
Calendar date = Calendar.getInstance();
String yearString = new Integer(date.get(Calendar.YEAR)).toString();
String oldYear = yearString.replace(",", "");
Map<String, Object> map = new HashMap<>();
map.put("orderId", "测试111111");
map.put("year", oldYear);
map.put("month", date.get(Calendar.MONTH) + 1);
map.put("day", date.get(Calendar.DAY_OF_MONTH));
return map;
}
}