html转pdf并且增加水印
1. html 文本不规范。
2. 转化pdf后,html样式丢失。
3. 转化后中文不显示。
4. 使用itextpdf增加水印时出现
Font "STSong-Light" with "UniGB-UCS2-H" is not recognized错误。
对于上面三个问题,网上有很多大同小异的说法,我不清楚别人是怎么解决问题的,我尝试按照网上的处理,把自己弄得晕晕的。
最后结合了我的实际情况,耐心找到了一个比较适合我自己的处理方式:
1. html 转pdf没什么好说的,方式很简单,直接上代码:
public static final void htmlToPdf(String htmlContent, String filePath) throws Exception {FileUtils.mkdir(new File(filePath).getParentFile(), true);
try (OutputStream fileStream = new FileOutputStream(filePath)) {
ITextRenderer textRenderer = new ITextRenderer();
ITextFontResolver fontResolver = textRenderer.getFontResolver();
String agreementBody = htmlContent;
agreementBody = agreementBody.replace(" ", " ");
agreementBody = agreementBody.replace("–", "–");
agreementBody = agreementBody.replace("—", "—");
agreementBody = agreementBody.replace("‘", "‘"); // left single quotation mark
agreementBody = agreementBody.replace("’", "’"); // right single quotation mark
agreementBody = agreementBody.replace("‚", "‚"); // single low-9 quotation mark
agreementBody = agreementBody.replace("“", "“"); // left double quotation mark
agreementBody = agreementBody.replace("”", "”"); // right double quotation mark
agreementBody = agreementBody.replace("„", "„"); // double low-9 quotation mark
agreementBody = agreementBody.replace("′", "′"); // minutes
agreementBody = agreementBody.replace("″", "″"); // seconds
agreementBody = agreementBody.replace("‹", "‹"); // single left angle quotation
agreementBody = agreementBody.replace("›", "›"); // single right angle quotation
agreementBody = agreementBody.replace("‾", "‾"); // overline
agreementBody = agreementBody.replace("×", "×");
agreementBody = agreementBody.replace("·", "·");
agreementBody = agreementBody.replace("€", "€");
fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", com.itextpdf.kernel.pdf.PdfName.IdentityH.getValue(), false);
fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont("C:/Windows/Fonts/arial.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
textRenderer.setDocumentFromString(agreementBody, null);
textRenderer.layout();
textRenderer.createPDF(fileStream, true);
}
}
其中htmlContent表示读取html的文本,filePath表示转成pdf后输出的文件路径,调用如下:
public static void main(String arg[]) {// html 地址,读取html文本
String htmlContent = "<html><body>" + readFile() + "</body></html>";
try {
// 转化为pdf
PDFUtil.htmlToPdf(htmlContent, "E:/PDF.pdf");
// pdf文件添加文字水印
PDFUtil.addPdfTextMark("E:/PDF.pdf", "E:/PDFWithMark.pdf", "测试文字水印", 300, 400);
// pdf文件添加图片水印
PDFUtil.addPdfImgMark("E:/PDF.pdf", "E:/PDFWithMark.pdf","D:/1.png", 0, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
readFile()方法只是我测试时读取本地一个html文本,如何读取html文本就不写了,这种例子很多。
我在转化过程中遇到第一个问题就是提示我:<br>标签没有关闭(img,input)。因为我是一个动态页面,在转化之前通过jquery获取<div>中的静态文本,本身我的代码是写的非常规范了,但是浏览器加载后通过jquery获取的文本就变成不规范的了,没啥办法,第一步只能是通过js把获取到的文本调整成规范化的,这里需要一点点耐心,我获取的就只有这三个标签不规范,所以浪费时间也不多,循环加上对应的关闭就好,因为我要转化的是商品房买卖合同文本,要规范的地方很固定,所以也没有去考虑其他更好的方式。
修改完成后接来下转化完成,就在我以为大功告成的时候让我懵逼的两个问题出现了:转化后的文件内容一个中文也没有,二维码位置,文字大小乱七八糟。
中文显示问题网上搜一下就好了,于是我在代码中增加了
fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", com.itextpdf.kernel.pdf.PdfName.IdentityH.getValue(), false);
fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont("C:/Windows/Fonts/arial.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
格式问题一开始就让我比较郁闷了,在<style></style>中写的格式一个也不起作用,反而直接在组件内部写的css例如<div style="font-size:24pt;">是没问题的,要知道商品房买卖合同的文本是二十多页的A4纸,我不可能把样式都写到每个组件里面,通过js在页面加载的时候把<style>组件中的样式加载到对应的class下。例如原来是:
.span_style { text-decoration: underline;
vertical-align: text-bottom;
text-align: center;
text-indent: 0;
font-size: 11pt;
}
$("#con-contentDiv").find("span").each(function() {var classText = $(this).attr("class");
if (!$.isEmpty(classText) && classText.indexOf("span_style") != -1 ) {
$(this).attr("style", "text-decoration: underline;vertical-align: text-bottom;text-align: center;text-indent: 0;font-size: 11pt;")
}
});
我就改成这样,对于像我这样需要通过jquery获取<div>内容的人来说,这两者的区别就是,前者加载后获取到的信息是<span class="span_style">,后者获取到的是<span style="text-decoration: underline;vertical-align: text-bottom;text-align: center;text-indent: 0;font-size: 11pt;">,就这样,我的转化后样式丢失问题也解决了。
最后就剩增加水印的问题了,网上有很多例子,从而我也尝试了很多,也不能说走了很多弯路吧,可能都不太适合我的应用场景。
最后找到了这个,算是完成了任务。
/** * pdf文件添加文字水印 * @param InPdfFile 要添加文字水印的pdf路径 * @param outPdfFile 添加水印之后的输出路径 * @param textMark 水印内容 * @param textWidth 文字横坐标 * @param textHeight 文字纵坐标 * @throws Exception */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)));
PdfContentByte under;
BaseFont font = 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.setFontAndSize(font, 38);// 文字水印 字体及字号
under.setTextMatrix(textWidth, textHeight);// 文字水印 起始位置
under.showTextAligned(Element.ALIGN_CENTER, textMark, textWidth, textHeight, 45);
under.endText();
}
stamp.close();// 关闭
}
/** * pdf文件添加图片水印 * @param InPdfFile 要添加水印的pdf路径 * @param outPdfFile 添加水印完成的pdf输入路径 * @param markImagePath 添加图片水印的路径 * @param imgWidth 添加水印X坐标:文件的四个角,左下方的角坐标为(0,0) * @param imgHeight 添加水印的Y坐标 * @throws Exception */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();// 关闭
}
以上是 html转pdf并且增加水印 的全部内容, 来源链接: utcz.com/z/513837.html