HTML生成PDF
一、html生成pdf需要引入jar包
在pom.xml中引入如下jar包
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.18</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.birt.runtime.3_7_1</groupId>
<artifactId>com.lowagie.text</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13</version>
<scope>compile</scope>
</dependency>
二、Java代码
import cn.qcdoc.common.core.exception.BaseException;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.AbstractImageProvider;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import com.itextpdf.tool.xml.pipeline.html.LinkProvider;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* html转PDF
*
* @author: wx
* @date: 2022/11/21
*/
public class HtmlPdfDemo {
public static String MakeHtml(List<String> listPath, String distPath, String templatePath){
String fileame = "test.html";
try {
String templateContent = "";
// 读取模板文件
FileInputStream fileinputstream = new FileInputStream(templatePath);
int length = fileinputstream.available();
byte bytes[] = new byte[length];
fileinputstream.read(bytes);
fileinputstream.close();
templateContent = new String(bytes);
StringBuilder sbPath = new StringBuilder();
for (String path : listPath) {
String imgs = "<img src=\""+path+"\"/>"+"\n"+"<div style='page-break-before: always;'>\n" +
"\t\t</div>";
sbPath.append(imgs);
}
String str = sbPath.toString().replace("\\", "/");
//把模板页面上的 ###image_list### 替换成 img 里的内容
templateContent = templateContent.replaceAll("###image_list###", str);
// 生成的html文件保存路径。
fileame = distPath + fileame;
// 建立文件输出流
FileOutputStream fileoutputstream = new FileOutputStream(fileame);
byte tag_bytes[] = templateContent.getBytes();
fileoutputstream.write(tag_bytes);
fileoutputstream.close();
} catch (Exception e) {
throw new BaseException("创建html失败!");
}
return fileame;
}
/**
* 创建PDF文件
* @author: wx
* @date: 2022/12/8
* @param: htmlPath html路径
* @param: outPdfPath 生成pdf路径
* @param: imagePath 图片路径
* @returns: void
*/
public static void writeToOutputStreamAsPDF(String htmlPath, String outPdfPath, String imagePath) throws Exception {
File targeFile = new File(outPdfPath);
if(targeFile.exists()) {
targeFile.delete();
}
//定义pdf文件尺寸,采用A4横切
Document document = new Document(PageSize.A4, 20, 20, 20, 20);// 左、右、上、下间距
//定义输出路径
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outPdfPath));
PdfReportHeaderFooter header = new PdfReportHeaderFooter("", 8, PageSize.A4);
writer.setPageEvent(header);
writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
document.open();
// HTML 设置
HtmlPipelineContext htmlContext = getHtmlPipelineContext(imagePath, null);
// Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(new StyleAttrCSSResolver(), html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream(htmlPath));
document.close();
}
/**
* html 设置
* @author: wx
* @date: 2022/10/13
* @param: imagePath
* @param: cssAppliers
* @returns: com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext
*/
private static HtmlPipelineContext getHtmlPipelineContext(String imagePath, CssAppliers cssAppliers) {
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.setImageProvider(new AbstractImageProvider() {
public String getImageRootPath() {
return imagePath;
}
});
htmlContext.setLinkProvider(new LinkProvider() {
public String getLinkRoot() {
return imagePath;
}
});
return htmlContext;
}
public static void main(String[] args) throws Exception {
List<String> listPath = new ArrayList<>();
listPath.add("1665989812537.jpg");
listPath.add("1665989815178.jpg");
String distPath = "upload\\depot\\electronic\\23335\\NJ01TYQABYM\\";
String templatePath = "upload\\depot\\table.html";
String outFilePath = "upload\\depot\\electronic\\23335\\NJ01TYQABYM\\test.pdf";
String htmlPath = MakeHtml(listPath, distPath, templatePath);
writeToOutputStreamAsPDF(htmlPath, outFilePath, distPath);
}
}
/**
* 调整pdf样式
*
* @author: wx
* @date: 2022/10/13
*/
class PdfReportHeaderFooter extends PdfPageEventHelper {
/**
* 页眉
*/
public String header = "";
/**
* 文档字体大小,页脚页眉最好和文本大小一致
*/
public int presentFontSize = 12;
/**
* 文档页面大小,最好前面传入,否则默认为A4纸张
*/
public Rectangle pageSize = PageSize.A4;
/**
* 模板
*/
public PdfTemplate total;
/**
* 基础字体对象
*/
public BaseFont bf = null;
/**
* 利用基础字体生成的字体对象,一般用于生成中文文字
*/
public Font fontDetail = null;
/**
* @param: yeMei 页眉字符串
* @param: presentFontSize 数据体字体大小
* @param: pageSize 页面文档大小,A4,A5,A6横转翻转等Rectangle对象
* @returns:
*/
public PdfReportHeaderFooter(String yeMei, int presentFontSize, Rectangle pageSize) {
this.header = yeMei;
this.presentFontSize = presentFontSize;
this.pageSize = pageSize;
}
/**
* 文档打开时创建模板
* @author: wx
* @date: 2022/10/14
* @param: writer
* @param: document
* @returns: void
*/
public void onOpenDocument(PdfWriter writer, Document document) {
// 页尾 共 页 的矩形的长宽高
total = writer.getDirectContent().createTemplate(50, 50);
}
/**
* 关闭每页的时候,写入页眉,写入'第几页共'这几个字。
* @author: wx
* @date: 2022/10/14
* @param: writer
* @param: document
* @returns: void
*/
public void onEndPage(PdfWriter writer, Document document) {
try {
if (bf == null) {
bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
}
if (fontDetail == null) {
fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 1.写入页眉
ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase(header, fontDetail), document.left(), document.top() + 20, 0);
// 2.写入前半部分的 第 X页/共
int pageS = writer.getPageNumber();
String foot1 = "第 " + pageS + " 页 /共";
Phrase footer = new Phrase(foot1, fontDetail);
// 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len
float len = bf.getWidthPoint(foot1, presentFontSize);
// 4.拿到当前的PdfContentByte
PdfContentByte cb = writer.getDirectContent();
// 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了 ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。
ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, footer, (document.rightMargin() + document.right() + document.leftMargin() - document.left() - len) / 2.0F + 20F, document.bottom() - 16, 0);
// 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F + len , y 轴和之前的保持一致,底边界-20
cb.addTemplate(total, (document.rightMargin() + document.right() + document.leftMargin() - document.left()) / 2.0F + 20F, document.bottom() - 16); // 调节模版显示的位置
}
/**
* 关闭文档时,替换模板,完成整个页眉页脚组件
* @author: wx
* @date: 2022/10/14
* @param: writer
* @param: document
* @returns: void
*/
public void onCloseDocument(PdfWriter writer, Document document) {
// 7.最后一步了,就是关闭文档的时候,将模板替换成实际的 Y 值,至此,page x of y 制作完毕,完美兼容各种文档size。
total.beginText();
total.setFontAndSize(bf, presentFontSize);// 生成的模版的字体、颜色
String foot2 = " " + (writer.getPageNumber() - 1) + " 页";
total.showText(foot2);// 模版显示的内容
total.endText();
total.closePath();
}
}
三、生成PDF文件
总结:
html生成pdf的时候,如果失败了,要检查对应的包是否引入错误,或者少引入jar。
本博客借鉴了网上的例子,在这里非常感谢其他博主的博客,让我在工作中解决了大量图片生成pdf的功能。
标签:String,import,html,生成,HTML,new,PDF,document,com From: https://www.cnblogs.com/why0703/p/16966867.html