项目中用到 iText 生成 PDF 文件,然后签章。先用 iText5 完成了一版,windows 下测试环境一切都看上去美极了,中文显示也很容易解决(用的 WINDOWS 自己的字体库)。但是,部署到 LINUX 运行系统上去后,一切都完全变了。无论怎么折腾,中文都不能正常显示,都是弯弯曲曲的乱码,重启机器也没用。
然后,发现了最新版本 iText7.
仔细一查,iText7 网络上的资料就很少,只好去看本身自带的 JAVADOC。应该说文档写得还是很不错的,例子代码也很连贯。看了例子,终于搞定。 考虑到百度的过程,决定整理一下,分享出来,供参考。
需要注意:iText7 跟 iText5 简直根本就是两个开发包,完全的重新设计,架构思路都完全不同,所以各位亲不用妄想自己用 iText5 写的程序,能轻松改一下就能用上 iText7。
iText7 解决中文显示问题的方式非常彻底,跟环境没啥关系,都是自己包里带的,不用担心各个操作系统兼容性问题。这个工具包真的很有意思,现在没时间研究,以后有时间的时候再补充。
我的使用需求比较简单,控制指定位置显示图片、文字、图文混排。就是下图的效果:
因为比较简单,直接上代码:
package com.yh.common.pdf;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.io.font.*;
import com.itextpdf.kernel.color.*;
import com.itextpdf.kernel.font.*;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.*;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.property.*;
import com.itextpdf.kernel.pdf.xobject.*;
import com.itextpdf.kernel.pdf.canvas.*;
import com.itextpdf.kernel.geom.*;
import com.itextpdf.io.image.*;
import com.itextpdf.kernel.pdf.PdfPage;
//import com.itextpdf.licensekey.*;
//import com.itextpdf.text.pdf.parser.PdfTextExtractor;
public class ExtractPDF7 {
public static String generatePDFFile(String OS, String filename, String[][] strContent, String[][] strColors,
String[] strIfChecked, String[] strSubTitles, String strTitle, String strDescPre, String strDescPost) {
int iTitleFontSize = 14, iSubTitleFontSize = 12, iFontSize = 11;
String IMGCHECKED = "../webapps/bjac/img/check.jpg";
String IMGNONCHECK = "../webapps/bjac/img/noncheck.jpg";
/*String IMGCHECKED = "C:/hyhportalworking/check.jpg";
String IMGNONCHECK = "C:/hyhportalworking/noncheck.jpg";*/
try {
PdfFont f = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);//中文设置
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(filename));
Document document = new Document(pdfDoc);
PdfPage currPage = null;
PdfCanvas canvas = null;
Paragraph paragraph = null;
String[] strIfCheckedTemp, strMultiLines;
String[] strTemps = null;
String strTemp = "";
int iStartPosX = 0, iStartPosY = 0, iLine = 0;
int iPageNum = strContent.length;
for (int k = 0; k < iPageNum; k++ ) {
currPage = pdfDoc.addNewPage(); /* 加一页 */
canvas = new PdfCanvas(currPage);
iLine = 0;
if (k == 0) { /* 首页写入标题和前置说明 */
if (strTitle != null) {
strMultiLines = strTitle.split("\n");
for (int m = 0; m < strMultiLines.length; m++) {
document.showTextAligned(new Paragraph(strMultiLines[m]).setFont(f).setFontSize(iTitleFontSize),
300, 800 - iLine * 30, pdfDoc.getPageNumber(currPage), TextAlignment.CENTER, VerticalAlignment.TOP, 0);
iLine = iLine + 2;
}
}
if (strDescPre != null) {
strMultiLines = strDescPre.split("\n");
for (int m = 0; m < strMultiLines.length; m++) {
document.showTextAligned(new Paragraph(strMultiLines[m]).setFont(f).setFontSize(iFontSize),
65, 800 - iLine * 20, pdfDoc.getPageNumber(currPage), TextAlignment.LEFT, VerticalAlignment.TOP, 0);
iLine = iLine + 1;
}
}
}
if ((strSubTitles != null) && (strSubTitles[k] != null)) { /* 写入每组的子标题 */
strMultiLines = strSubTitles[k].split("\n");
for (int m = 0; m < strMultiLines.length; m++) {
document.showTextAligned(new Paragraph(strMultiLines[m]).setFont(f).setFontSize(iSubTitleFontSize),
40, 800 - iLine * 20, pdfDoc.getPageNumber(currPage), TextAlignment.LEFT, VerticalAlignment.TOP, 0);
iLine = iLine + 1;
}
}
/* 开始处理一组 */
strTemps = strContent[k];
strIfCheckedTemp = strIfChecked[k].split(";");
for (int i = 0; i < strTemps.length; i++) {
iStartPosY = 763 - iLine * 20;
if (strTemps[i].startsWith("check ") ) {
if ((i < strIfCheckedTemp.length) && (strIfCheckedTemp[i] != null) && strIfCheckedTemp[i].equals("1")) {
canvas.addImage(ImageDataFactory.create(IMGCHECKED), 40, (iStartPosY - 15), 12, true);
}
else {
canvas.addImage(ImageDataFactory.create(IMGNONCHECK), 40, (iStartPosY - 15), 12, true);
}
strTemp = strTemps[i].substring(6);
iStartPosX = 70;
}
else {
strTemp = strTemps[i];
if (strTemp.startsWith("【") ) iStartPosX = 65;
else iStartPosX = 40;
}
paragraph = new Paragraph(strTemp).setFont(f).setFontSize(iSubTitleFontSize);
if ((strColors[k] != null) && (strColors[k][i] != null)) {
if (strColors[k][i].endsWith("blue")) paragraph.setFontColor(new DeviceRgb(0, 0, 255));
else if (strColors[k][i].endsWith("red")) paragraph.setFontColor(new DeviceRgb(255, 0, 0));
else if (strColors[k][i].endsWith("indent")) iStartPosX = 265;
}
else paragraph.setFontColor(new DeviceRgb(0, 0, 0));
strMultiLines = strTemp.split("\n");
for (int m = 0; m < strMultiLines.length; m++) {
document.showTextAligned(paragraph, iStartPosX, iStartPosY, pdfDoc.getPageNumber(currPage), TextAlignment.LEFT, VerticalAlignment.TOP, 0);
iLine ++;
if (iLine > 35) { /* 加一页 */
currPage = pdfDoc.addNewPage(); /* 加一页 */
canvas = new PdfCanvas(pdfDoc.getLastPage());
iLine = 0;
}
}
}
}
/* 最后写入尾部说明 */
if (strDescPost != null) {
strMultiLines = strDescPost.split("\n");
for (int m = 0; m < strMultiLines.length; m++) {
document.add(new Paragraph(strMultiLines[m]).setFont(f).setFontSize(iFontSize));
iLine = iLine + 1;
}
}
document.close();
}
catch(Exception e) {
return e.getMessage();
}
return "T";
}
}