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

回到顶部