java工具类之html转PDF工具类

工具类:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;

/**
 * html转PDF工具类
 * 
 * @author zql
 *
 */
public class HtmlToPDF {

	private static final Logger logger = Logger.getLogger(HtmlToPDF.class);
	
	/**
	 * html模板生成PDF文件输出
	 * 此方法需要maven支持如下:
	 * 
* <dependency> *
* <groupId>org.xhtmlrenderer</groupId> *
* <artifactId>core-renderer</artifactId> *
* <version>R8</version> *
* </dependency> * * @param htmlPath html模板文件路径 * @param map 要替换的字段值 * @param pdfPath pdf输出路径 * @throws Exception */
public static void generatePdf(String htmlPath, Map<String, String> map, String pdfPath) throws Exception { try { OutputStream outputFile = new FileOutputStream(pdfPath); // 获取html String形式 String htmlStr = operateHtml(htmlPath, map); ITextRenderer renderer = new ITextRenderer(); ITextFontResolver font = renderer.getFontResolver(); String sysPath = System.getProperty("user.dir"); String fontPath = sysPath + "\\src\\fonts\\simsun.ttc"; // 添加中文识别,这里是设置的宋体,Linux下要换成对应的字体,中文不显示则给不显示的标签加上样式font-family:'SimSun'; font.addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); renderer.setDocumentFromString(htmlStr); renderer.layout(); renderer.createPDF(outputFile); renderer.finishPDF(); logger.info("PDF is generate.------------------------------"); } catch (IOException e) { logger.info("HtmlToPDF.generatePdf occoured IOException! Message:" + e.getMessage()); throw e; } catch (DocumentException e) { logger.info("HtmlToPDF.generatePdf occoured DocumentException! Message:" + e.getMessage()); throw e; } } /** * html模板生成PDF文件输出 * * @param htmlPath html模板文件路径 * @param map 要替换的字段值 * @param outputFile 输出文件形式 * @throws Exception */ public static void generatePdf(String htmlPath, Map<String, String> map, OutputStream outputFile) throws Exception { Document document = null; InputStream in = null; try { // 获取html String形式 String htmlStr = operateHtml(htmlPath, map); // 创建输入html流 in = stringToInputStream(htmlStr); // 第一步 document = new Document(); // 第二步 PdfWriter writer = PdfWriter.getInstance(document, outputFile); // 第三步 document.open(); // 第四步 解决中文支持问题,中文不显示则给不显示的标签加上样式font-family:'SimSun'; XMLWorkerHelper.getInstance().parseXHtml(writer, document, in, Charset.forName("UTF-8")); // 第五步 in.close(); document.close(); logger.info("PDF is generate.------------------------------"); } catch (IOException e) { logger.info("HtmlToPDF.generatePdf occoured IOException! Message:" + e.getMessage()); throw e; } catch (DocumentException e) { logger.info("HtmlToPDF.generatePdf occoured DocumentException! Message:" + e.getMessage()); throw e; } finally { if (in != null) { in.close(); } if (document != null) { document.close(); } } } /** * String转InputStream * * @param str * @return */ private static InputStream stringToInputStream(String str) { InputStream in = new ByteArrayInputStream(str.getBytes()); return in; } /** * InputStream转String * * @param in * @return */ @SuppressWarnings("unused") private static String inputStreamToString(InputStream in) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int i = 1; try { while ((i = in.read()) != -1) { baos.write(i); } } catch (Exception e) { e.printStackTrace(); } return baos.toString(); } /** * 读取html模板文件并替换参数值 * * @param htmlPath html文件路径 * @param map 要替换的参数值 * @return * @throws Exception */ private static String operateHtml(String htmlPath, Map<String, String> map) throws Exception { // html字符串 String htmlStr = ""; File htmlFile = null; try { htmlFile = new File(htmlPath); //获取htmlStr jsoup,建议使用,会补全缺失的 org.jsoup.nodes.Document html = Jsoup.parse(htmlFile,"UTF-8"); htmlStr = html.html(); // 解决中文问题 htmlStr = htmlStr.replaceAll("font-family:[^;]*;", "font-family:'SimSun';"); // 解决docx中文问题 htmlStr = htmlStr.replaceAll("width:[^;]*;", ""); htmlStr = htmlStr.replaceAll("margin-bottom:[^;]*;", ""); htmlStr = htmlStr.replaceAll("margin-left:[^;]*;", ""); htmlStr = htmlStr.replaceAll("margin-right:[^;]*;", ""); htmlStr = htmlStr.replaceAll("margin-top:[^;]*;", ""); htmlStr = htmlStr.replaceAll("p\\.[^\\}]*\\}", ""); htmlStr = htmlStr.replaceAll("span\\.[^\\}]*\\}", ""); htmlStr = htmlStr.replaceAll("

", "

"); //将未闭合的标签 闭合 htmlStr = expectedClosingTag(htmlStr, "(]*[^/]>)|(]*[^/]>)"); //表格线条错误粗修改 htmlStr = htmlStr.replaceAll("thin solid black", "1"); //替换特殊字段 字段形式 如: ${test} for (Map.Entry<String, String> entry : map.entrySet()){ htmlStr = htmlStr.replaceAll("\\$\\{" + entry.getKey() + "\\}", entry.getValue()); htmlStr = htmlStr.replaceAll("\\$\\{[^\\}]*" + entry.getKey() + "[^\\}]*\\}", entry.getValue()); } // 将未赋值的去除 htmlStr = htmlStr.replaceAll("\\$\\{[^\\}]*[^\\}]*\\}", "    "); // 将body标签内样式去掉,并加上font-family:'SimSun';解决中文不显示问题 htmlStr = htmlStr.replaceAll("]*>", ""); } catch (Exception e) { logger.info("HtmlToPDF.operateHtml occoured Exception! Message:" + e.getMessage()); throw e; } finally { if (htmlFile != null) { htmlFile.delete(); } } return htmlStr; } /** * 处理html meta标签,使meta标签闭合 * @param htmlStr * @param regex * @return */ private static String expectedClosingTag(String htmlStr, String regex) { Pattern p = Pattern.compile(regex); Matcher m = p.matcher(htmlStr); List<String> result = new ArrayList<String>(); while (m.find()) { result.add(m.group()); } for (String str : result) { int strLen = str.length(); if (str != null && strLen > 1) { logger.debug("In need of replacement:" + str); htmlStr = htmlStr.replace(str, str.substring(0, strLen - 1) + "/>"); } } return htmlStr; } /** * 获取当前操作系统 * * @return */ public static String getCurrentOperatingSystem(){ String os = System.getProperty("os.name").toLowerCase(); logger.debug("---------当前操作系统是-----------" + os); return os; } }

测试类:

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


public class HtmlToPDFTest {

	@SuppressWarnings("static-access")
	public static void main(String[] args) throws Exception {
		/* 用log4包加载配置文件 */
//		PropertyConfigurator.configure(System.getProperty("user.dir") + "\\src\\log4j.properties");
		/* 用java自带peoperties加载配置文件  */
		Properties props=new Properties();
		try {
			props.load(HtmlToPDFTest.class
                 .getClassLoader()
                 .getResourceAsStream("log4j.properties")
                 );
		} catch (IOException e) {
			e.printStackTrace();
		}
		String htmlFile1 = "E:/test/test1.html";
		String htmlFile2 = "E:/test/test2.html";
		String pdfFile1 = "E:/test/test1.pdf";
		String pdfFile2 = "E:/test/test2.pdf";
		
		Map<String, String> map = new HashMap<String, String>();
		map.put("test1", "测试1");
		map.put("test2", "测试2");
		map.put("test3", "测试3");
		map.put("test4", "测试4");
		new HtmlToPDF().generatePdf(htmlFile1, map, pdfFile1);
		new HtmlToPDF().generatePdf(htmlFile2, map, new FileOutputStream(pdfFile2));
	}
}

maven依赖:


<dependency>
    <groupId>org.xhtmlrenderergroupId>
    <artifactId>core-rendererartifactId>
    <version>R8version>
dependency>
      


<dependency>
    <groupId>com.itextpdfgroupId>
    <artifactId>itextpdfartifactId>
    <version>5.4.0version>
dependency>

<dependency>
    <groupId>com.itextpdf.toolgroupId>
    <artifactId>xmlworkerartifactId>
    <version>5.4.0version>
dependency>
      

<dependency>
    <groupId>org.slf4jgroupId>
    <artifactId>slf4j-log4j12artifactId>
    <version>1.7.2version>
dependency>

<dependency>
    <groupId>org.jsoupgroupId>
    <artifactId>jsoupartifactId>
    <version>1.7.2version>
dependency>

你可能感兴趣的:(#,java工具类)