html 转PDF

1,525 阅读2分钟

依赖

<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>html2pdf</artifactId>
  <version>2.0.2</version>
</dependency>
<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>itext-asian</artifactId>
  <version>5.2.0</version>
</dependency>

实现 ```java

@Component
public class PDFUtil {

	private static String filePath;

	private static ConverterProperties props = new ConverterProperties();

	// 加载中文字体放置linux下导出的pdf中文乱码
	static {
		// 加载环境字体
	    DefaultFontProvider defaultFontProvider = new DefaultFontProvider(true, true, true);
	    // 添加中文字体(针对linux的)
	    defaultFontProvider.addFont("/home/vcap/app/WEB-INF/fonts/DENG.TTF");
	    props.setFontProvider(defaultFontProvider);
	}


	public static ByteArrayOutputStream html2Pdf(Map<Object, Object> reportParam, boolean ifPage)
			throws FileNotFoundException, IOException {
		String html = (String) reportParam.get("html");
		// 客户端dpi值 dpix: 横向;dpiy:纵向
		int dpix = NumberUtils.parseNumber(reportParam.get("dpix").toString(), Integer.class);
		int dpiy = NumberUtils.parseNumber(reportParam.get("dpiy").toString(), Integer.class);
		// table 的宽高像素值
		Object widthStr = reportParam.get("width");
		Object heightStr = reportParam.get("height");
		Float width = widthStr == null ? 0 : NumberUtils.parseNumber(widthStr.toString(), Float.class);
		Float height = heightStr == null ? 0 : NumberUtils.parseNumber(heightStr.toString(), Float.class);
		// 72:itext内部定义的dpi单位(dpi是图像每英寸面积内的像素点数;36是left-margin和right-margin的值;dpix是客户端显示器的dpi值)
		// 像素转换
		width = convertSize(width, dpix) + 36 * 2;
		height = convertSize(height, dpiy);
		if (height > PageSize.A4.getHeight() && ifPage) {
			height = PageSize.A4.getHeight();
		}

		ByteArrayOutputStream bao = new ByteArrayOutputStream();
		PdfWriter writer = new PdfWriter(bao);
		PdfDocument pdf = new PdfDocument(writer);
		pdf.setDefaultPageSize(new PageSize(width, height));
		Document document = HtmlConverter.convertToDocument(html, pdf, props);
		document.getRenderer().close();
		document.close();
		return bao;
	}

	
	public static String html2PdfByPages(Map<Object, Object> reportParam, HttpServletRequest request) throws Throwable {
		PageBuilder pb = (PageBuilder) reportParam.get("pageBuilder");
		// 获取各页的html
		IReport[] iReports = pb.getAllPages();
		String[] htmls = new String[iReports.length];
		ReportParser parser = new ReportParser(iReports[0]);
		for (int i = 0; i < iReports.length; i++) {
			IReport iReportTemp = pb.getPage(i + 1);
			String html = ReportUtils.toHTMLString(iReportTemp, "report" + i, request);
			htmls[i] = html;
		}
		
		// 客户端dpi值 dpix: 横向;dpiy:纵向
		int dpix = NumberUtils.parseNumber(request.getParameter("dpix"), Integer.class);
		int dpiy = NumberUtils.parseNumber(request.getParameter("dpiy"), Integer.class);
		// table 的宽高像素值
		Object widthStr = reportParam.get("width");
		Float width = widthStr == null ? 0 : NumberUtils.parseNumber(widthStr.toString(), Float.class);
		Float height = (float) parser.getReportEditHeight(); 
		// 72:itext内部定义的dpi单位(dpi是图像每英寸面积内的像素点数;36是left-margin和right-margin的值;dpix是客户端显示器的dpi值)
		// 像素转换
		width = convertSize(width, dpix) + 36 * 2;
		height = convertSize(height, dpiy);

		String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".pdf";
		String dest = filePath + "/download/" + fileName;
		PdfWriter writer = new PdfWriter(dest);
		PdfDocument document = new PdfDocument(writer);
		PdfMerger merger = new PdfMerger(document);
		// 合并pdf为一个
		ByteArrayOutputStream bao = null;
		PdfWriter pw = null;
		PdfDocument pdf = null;
		for (String html : htmls) {
			bao = new ByteArrayOutputStream();
			pw = new PdfWriter(bao);
			pdf = new PdfDocument(pw);
			pdf.setDefaultPageSize(new PageSize(width, height));
			HtmlConverter.convertToPdf(html, pdf, props);
			pdf = new PdfDocument(new PdfReader(new ByteArrayInputStream(bao.toByteArray())));
			merger.merge(pdf, 1, pdf.getNumberOfPages());
			pdf.close();
			bao.close();
		}
		document.close();
		return fileName;
	}

	
	private static float convertSize(float size, int dpi) {
		return size * 72 / dpi;
	}

	@Value("${web.root.path}")
	public void setFilePath(String filePath) {
		PDFUtil.filePath = filePath + "/WEB-INF/";
	}

}
```