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;
}
}