html转PDF方法类
import com.itextpdf.text.*;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.lingzhi.common.utils.file.FileUploadUtils;
import com.lingzhi.common.utils.html.HtmlConvertWordUtil;
import com.lowagie.text.Font;
import com.lowagie.text.pdf.BaseFont;
import com.spire.ms.System.Collections.ArrayList;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import fr.opensagres.xdocreport.itext.extension.font.IFontProvider;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Entities;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
public class PdfUtils {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String DEFAULT_ORDER_CSS = "table{border-collapse:collapse;border-spacing:0;width:100%;border-bottom:1px solid #222;border-right:1px solid #222;margin-top:20pt;margin-bottom:20pt;}*{font-size:10.5pt;font-family:SimSun;line-height:1.8}a{text-decoration:none;color:black}td,th{border-top:1px solid #222;border-left:1px solid #222;padding:8px 0;text-align:center;white-space:normal;word-wrap:break-word;word-break:break-all;}h1,h1 a,h1 a strong{font-size:29.26pt;font-weight:bold;}h2,h2 a,h2 a strong{font-size:17.56pt;font-weight:bold;}h3,h3 a,h3 a strong{font-size:15.61pt;font-weight:bold;}h4,h4 a,h4 a strong{font-size:13.66pt;font-weight:bold;}h5,h5 a,h5 a strong{font-size:11.70pt;font-weight:bold;}h6,h6 a,h6 a strong{font-size:9.75pt;font-weight:bold;}h1,h2,h3,h4,h5,h6{font-weight:bolder}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:bolder}thead tr:nth-child(1){width:12% !important;}thead tr:nth-child(2){width:12% !important;}thead tr:nth-child(3){width:10% !important;}thead tr:nth-child(4){width:8% !important;}thead tr:nth-child(5){width:8% !important;}thead tr:nth-child(6){width:8% !important;}thead tr:nth-child(7){width:11% !important;}thead tr:nth-child(8){width:11% !important;}thead tr:nth-child(9){width:10% !important;}thead tr:nth-child(10){width:10% !important;}thead th:nth-child(1){font-weight:normal;font-size:14px;width:12% !important;}thead th:nth-child(2){font-weight:normal;font-size:14px;width:12% !important;}thead th:nth-child(3){font-weight:normal;font-size:14px;width:10% !important;}thead th:nth-child(4){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(5){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(6){font-weight:normal;font-size:14px;width:8% !important;}thead th:nth-child(7){font-weight:normal;font-size:14px;width:11% !important;}thead th:nth-child(8){font-weight:normal;font-size:14px;width:11% !important;}thead th:nth-child(9){font-weight:normal;font-size:14px;width:10% !important;}thead th:nth-child(10){font-weight:normal;font-size:14px;width:10% !important;}.left{width:100%;display:table:text-align:left;float:left}.right{width:100%;display:table:text-align:right;float:right}.none-border,.none-border td,.none-border th{border:none;}";
final static String[] colWidth = {"12%", "12%", "10%", "8%", "8%", "8%", "12%", "10%", "10%", "10%"};
public void exportPdf(HttpServletResponse response, String filename, String content, String watermark) throws Exception {
if (content == null || content.length() <= 0) return;
OutputStream os = null;
OutputStream tempos = null;
InputStream tempStream = null;
try {
content=content.replace("","").replace("","");
// XML5个转义符:<,>,&,",©;的转义字符分别如下: < >& " '
content = content.replaceAll("<","<").replaceAll(">",">").replaceAll("&","&").replaceAll(""",""").replaceAll("'","©");
content = content.replaceAll(" ","").replaceAll(" ","").replaceAll(" ","").replaceAll(" ","").replaceAll(" ","");
content = content.replaceAll("©","©").replaceAll("®","TM").replaceAll("×","×").replaceAll("÷","÷");
String html="" +
"n" +
"n" +
"n" +
" n" +
" "+filename+" n" +
""+
"n" +
"n" +
content +
"nn" +
"";
// 通过Jsoup格式化html
Document parse = Jsoup.parse(html);
// 获取html中所有的标签元素
Elements es = parse.body().getAllElements();
List> imglist = new ArrayList();
// 筛选标签
java.util.List tag1 = es.stream().filter(x -> "img".equals(x.tagName())).collect(Collectors.toList());
for (org.jsoup.nodes.Element imgElement : tag1) {
//处理图片
Attributes as = imgElement.attributes();
String src = as.get("src");
HttpServletRequest request = ServletUtils.getRequest();
String ur = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort();
String pictureUrl = "";
if(src.contains("//")){
pictureUrl = src;
}else{
pictureUrl = ur+src;
HashMap imgmap=new HashMap<>();
imgmap.put("src1",src);
imgmap.put("src2",pictureUrl);
imglist.add(imgmap);
}
//设置图片宽度
int pagewidth = Math.round(PageSize.A4.getWidth());
try
{
Image img = Image.getInstance(pictureUrl);
if(img.getWidth()>pagewidth)
{
imgElement.attr("style","width:100%");
}
} catch (Exception ex) {
}
}
String _html = parse.html();
String xhtml = htmlToxhtml(_html);
xhtml=xhtml.replace(" ","");
for(HashMap item : imglist)
{
xhtml = xhtml.replace(item.get("src1"),item.get("src2"));
}
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(xhtml);
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont("/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont("/Fonts/SimSun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont("/Fonts/simsunbd.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//浏览器导出
renderer.layout();
response.setCharacterEncoding("utf-8");
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment;filename="+new String((filename+".pdf").getBytes("utf-8"),"ISO8859-1"));
os = response.getOutputStream(); //创建输出流
if(StringUtils.isEmpty(watermark))
{
renderer.createPDF(os);
renderer.finishPDF();
}
else
{
//添加水印
String tempPath = FileUploadUtils.getDefaultBaseDir()+"/Temporary";
File file = new File(tempPath);
if (!file.exists() && !file.isDirectory())
{
file.mkdir();
}
String tempPath1 = tempPath+"/temp1.pdf";
String tempPath2 = tempPath+"/temp2.pdf";
tempos = new FileOutputStream(new File(tempPath1));
renderer.createPDF(tempos);
renderer.finishPDF();
tempos.flush();
tempos.close();
addPdfTextMark(tempPath1,tempPath2,watermark,50,50);
tempStream = new FileInputStream(tempPath2);
int c = 0;
byte[] buf = new byte[8192];
while ((c = tempStream.read(buf, 0, buf.length)) > 0) {
os.write(buf, 0, c);
os.flush();
}
tempStream.close();
FileUploadUtils.deFile(tempPath1);
FileUploadUtils.deFile(tempPath2);
}
os.flush();
os.close();
} catch (Exception e) {
if(os != null) os.close();
if(tempos != null) tempos.close();
if(tempStream != null) tempStream.close();
throw e;
}
}
public void exportPdf2(HttpServletResponse response, String filename, String content, String watermark) throws Exception {
if (content == null || content.length() <= 0) return;
OutputStream os = null;
OutputStream tempos = null;
InputStream tempStream = null;
try {
String tempPath = FileUploadUtils.getDefaultBaseDir()+"/Temporary";
File file = new File(tempPath);
if (!file.exists() && !file.isDirectory())
{
file.mkdir();
}
String tempPath1 = tempPath+"/temp1.pdf";
String tempPath2 = tempPath+"/temp2.pdf";
String tempPath0 = tempPath + "/temp0.docx";
XWPFDocument docxDocument = HtmlConvertWordUtil.htmlConvertWord(content);
FileOutputStream out = new FileOutputStream(tempPath0);
docxDocument.write(out);
out.close();
ConvertDocxToPdf(new FileInputStream(tempPath0), new FileOutputStream(tempPath1));
tempos = new FileOutputStream(new File(tempPath1));
tempos.flush();
tempos.close();
response.setCharacterEncoding("utf-8");
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment;filename="+new String((filename+".pdf").getBytes("utf-8"),"ISO8859-1"));
os = response.getOutputStream(); //创建输出流
createWithHtml(content,"",new FileOutputStream(new File(tempPath1)));
if(StringUtils.isEmpty(watermark))
{
tempStream = new FileInputStream(tempPath1);
}
else
{
//添加水印
addPdfTextMark(tempPath1,tempPath2,watermark,50,50);
tempStream = new FileInputStream(tempPath2);
}
int c = 0;
byte[] buf = new byte[8192];
while ((c = tempStream.read(buf, 0, buf.length)) > 0) {
os.write(buf, 0, c);
os.flush();
}
tempStream.close();
//FileUploadUtils.deFile(tempPath0);
FileUploadUtils.deFile(tempPath1);
FileUploadUtils.deFile(tempPath2);
os.flush();
os.close();
} catch (Exception e) {
if (os != null) os.close();
if (tempos != null) tempos.close();
if (tempStream != null) tempStream.close();
throw e;
}
}
public String htmlToxhtml(String html) {
Document doc = Jsoup.parse(html);
doc.outputSettings().syntax(Document.OutputSettings.Syntax.xml).escapeMode(Entities.EscapeMode.xhtml);
return doc.html();
}
public void ConvertDocxToPdf(InputStream fileInputStream, OutputStream fileOutputStream){
try {
//添加依赖org.apache.poi.xwpf.converter.pdf和xdocreport都需要
XWPFDocument xwpfDocument = new XWPFDocument(fileInputStream);
PdfOptions pdfOptions = PdfOptions.create();
//中文字体处理
pdfOptions.fontProvider(new IFontProvider() {
@Override
public Font getFont(String familyName, String s1, float v, int i, Color color) {
try {
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font fontChinese = new Font(bfChinese, v, i, color);
if (familyName != null)
fontChinese.setFamily(familyName);
return fontChinese;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
});
PdfConverter.getInstance().convert(xwpfDocument,fileOutputStream,pdfOptions);
fileInputStream.close();
fileOutputStream.close();
}
catch (Exception ex)
{
String aa=ex.getMessage();
}
}
public static void addPdfTextMark(String InPdfFile, String outPdfFile, String textMark, int textWidth, int textHeight) throws Exception {
PdfReader reader = new PdfReader(InPdfFile, "PDF".getBytes());
PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(new File(outPdfFile)));
try
{
PdfContentByte under;
PdfGState gs1 = new PdfGState();
gs1.setFillOpacity(0.8f);// 透明度设置
com.itextpdf.text.pdf.BaseFont font =com.itextpdf.text.pdf.BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1", "Identity-H", true);// 使用系统字体
int pageSize = reader.getNumberOfPages();// 原pdf文件的总页数
for (int i = 1; i <= pageSize; i++) {
//under = stamp.getUnderContent(i);// 水印在之前文本下
under = stamp.getOverContent(i);//水印在之前文本上
under.beginText();
under.setColorFill(new BaseColor(211,211,211));// 文字水印 颜色
under.setGState(gs1);// 图片水印 透明度
under.setFontAndSize(font, 32);// 文字水印 字体及字号
under.setTextMatrix(textWidth, textHeight);// 文字水印 起始位置
//under.showTextAligned(Element.ALIGN_CENTER, textMark, textWidth, textHeight, 45);
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 3; y++) {
under.showTextAligned(Element.ALIGN_LEFT, textMark, x*200+100, y*200+x*100, 45);
}
}
under.endText();
}
stamp.close();// 关闭
reader.close();
}
catch (Exception e)
{
if(reader != null) reader.close();
if(stamp != null) stamp.close();
throw e;
}
}
public static void addPdfImgMark(String InPdfFile, String outPdfFile, String markImagePath, int imgWidth, int imgHeight) throws Exception {
PdfReader reader = new PdfReader(InPdfFile, "PDF".getBytes());
PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(new File(outPdfFile)));
PdfContentByte under;
PdfGState gs1 = new PdfGState();
gs1.setFillOpacity(0.8f);// 透明度设置
Image img = Image.getInstance(markImagePath);// 插入图片水印
img.setAbsolutePosition(imgWidth, imgHeight); // 坐标
img.setRotation(0);// 旋转 弧度
img.setRotationDegrees(0);// 旋转 角度
img.scaleAbsolute(595, 842);// 自定义大小
// img.scalePercent(50);//依照比例缩放
int pageSize = reader.getNumberOfPages();// 原pdf文件的总页数
for (int i = 1; i <= pageSize; i++) {
under = stamp.getUnderContent(i);// 水印在之前文本下
// under = stamp.getOverContent(i);//水印在之前文本上
under.setGState(gs1);// 图片水印 透明度
under.addImage(img);// 图片水印
}
stamp.close();// 关闭
}
public void createWithHtml(String templateString,String extraHtml, OutputStream outputStream) throws Exception{
com.itextpdf.text.Document document = new com.itextpdf.text.Document();
//页面竖向
Rectangle pageSize = new Rectangle(PageSize.A4.getWidth(), PageSize.A4.getHeight());
pageSize.rotate();
document.setPageSize(pageSize);
PdfWriter pdfWriter = PdfWriter.getInstance(document,outputStream);
int width = Math.round(PageSize.A4.getWidth());
document.open();
document.addCreationDate();
XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
String mdContent = templateString;
Charset charset = Charset.forName("utf-8"); //Charset.forName("GBK");
String htmlContent = "" + templateString + "";
org.jsoup.nodes.Document htmlDoc = Jsoup.parse(htmlContent, "", Parser.xmlParser());
org.jsoup.select.Elements centerEle = htmlDoc.select("center");
Elements tblist = htmlDoc.select("table");
if(tblist!=null){
for(org.jsoup.nodes.Element element : tblist){
element.attr("width","100%");
}
}
//处理h1~h6问题
Elements aList = htmlDoc.select("h1 a,h2 a,h3 a,h4 a,h5 a,h6 a");
if(aList != null)
{
for (org.jsoup.nodes.Element a : aList) {
String text = a.text();
a.text("");
a.appendElement("strong");
a.child(0).text(text);
}
}
Elements imglist = htmlDoc.select("img");
if(imglist != null)
{
for (org.jsoup.nodes.Element a : imglist)
{
//处理图片
Attributes as = a.attributes();
String src = as.get("src");
HttpServletRequest request = ServletUtils.getRequest();
String ur = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort();
String pictureUrl = "";
if(src.contains("//")){
pictureUrl = src;
}else{
pictureUrl = ur+src;
}
try
{
Image img = Image.getInstance(pictureUrl);
if(img.getWidth()>width)
{
int imgwidth = Math.round(width*100/80);
int imgheight = Math.round(img.getHeight()*width/imgwidth);
img.scaleAbsolute(imgwidth,imgheight);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
String bodyContent = htmlDoc.select("body").html();
bodyContent = htmlToxhtml(bodyContent);
worker.parseXHtml(pdfWriter, document, new ByteArrayInputStream(bodyContent.getBytes(charset))
, new ByteArrayInputStream(DEFAULT_ORDER_CSS.getBytes())
,charset
, new AsianFontProvider("/Fonts/SimSun.ttf","/Fonts/simsunbd.ttf"));
document.close();
pdfWriter.close();
}
}



