java操作pdf之iText快速入门
iText是著名的开放项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。
iText官网: http://itextpdf.com/
官网示例: http://itextpdf.com/examples/
更多示例: https://kb.itextpdf.com/home/it5kb/examples
Maven依赖:
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
pdf和iText简介
第一个iText示例:Hello World
public class HelloWorld {
public static final String RESULT
= "src/main/resources/hello.pdf";
/**
* 创建一个pdf文件: hello.pdf
*/
public static void main(String[] args)
throws DocumentException, IOException {
new HelloWorld().createPdf(RESULT);
}
//五个步骤
public void createPdf(String filename)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
PdfWriter.getInstance(document, new FileOutputStream(filename));
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello World!"));
// step 5
document.close();
}
}
自定义页面大小
通过 Document构造函数来设置页面的大小尺寸和 页面边距。
Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop, float marginBottom)
其中通过 Rectangle(宽,高)来指定pdf页面的尺寸大小,通过marginLeft marginRight marginTop marginBottom来设置页面边距.
Rectangle pagesize = new Rectangle(216f, 720f);
Document document = new Document(pagesize, 36f, 72f, 108f, 180f);
或者
通过PageSize.LETTER来指定页面的大小。在实际开发中PageSize.A4使用的比较多。如果构造不指定的话默认就是PageSize.A4 页边距全是36pt。
Document document = new Document(PageSize.LETTER);
常用属性
//设置作者
document.addAuthor("ZBK");
//设置创建日期
document.addCreationDate();
// 设置创建者
document.addCreator("张宝奎");
// 设置生产者
document.addProducer();
// 设置关键字
document.addKeywords("my");
//设置标题
document.addTitle("标题");
//设置主题
document.addSubject("主题");
最大页面尺寸
public class HelloWorldMaximum {
public static final String RESULT = "src/main/resources/hello_maximum.pdf";
public static void main(String[] args)
throws DocumentException, IOException {
// 第一步
//最大页面尺寸
Document document = new Document(new Rectangle(14400, 14400));
// 第二步
PdfWriter writer =PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// 改变用户单位 UserUnit是定义默认用户空间单位的值。最小UserUnit为1(1个单位= 1/72英寸)。最大UserUnit为75,000。
writer.setUserunit(75000f);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello World"));
// step 5
document.close();
}
}
横向显示pdf
通过**rotate()**方法
Document document = new Document(PageSize.LETTER.rotate());
或者
通过设置宽和高
Document document = new Document(new Rectangle(792, 612));
设置页边距和装订格式
对于需要装订成册的多页pdf,如果是左右装订(正反面打印)的话我们第一页的左边距要与第二页的右边距一样,第一页的右边距要与第二页的左边距一样,也就是保证页边距要对称。
通过 setMargins设置页边距,通过setMarginMirroring(true) 来设置两页的边距对称
注意: 如果是上下装订的方式装订,则通过**setMarginMirroringTopBotton(true)**来设置两页的边距对称.
public class HelloWorldMirroredMargins {
public static final String RESULT
= "src/main/resources/hello_mirrored_margins.pdf";
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
PdfWriter.getInstance(document, new FileOutputStream(RESULT));
document.setPageSize(PageSize.A5);
document.setMargins(36, 72, 108, 180);
document.setMarginMirroring(true); //设置边距对称
// step 3
document.open();
// step 4
document.add(new Paragraph(
"The left margin of this odd page is 36pt (0.5 inch); " +
"the right margin 72pt (1 inch); " +
"the top margin 108pt (1.5 inch); " +
"the bottom margin 180pt (2.5 inch)."));
Paragraph paragraph = new Paragraph();
paragraph.setAlignment(Element.ALIGN_JUSTIFIED);
for (int i = 0; i < 20; i++) {
paragraph.add("Hello World! Hello People! " +
"Hello Sky! Hello Sun! Hello Moon! Hello Stars!");
}
document.add(paragraph);
document.add(new Paragraph(
"The right margin of this even page is 36pt (0.5 inch); " +
"the left margin 72pt (1 inch)."));
// step 5
document.close();
}
}
内存中操作pdf文件
public class HelloWorldMemory {
public static final String RESULT = "src/main/resources/hello_memory.pdf";
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
// we'll create the file in memory
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello World!"));
// step 5
document.close();
// let's write the file in memory to a file anyway
FileOutputStream fos = new FileOutputStream(RESULT);
fos.write(baos.toByteArray());
fos.close();
}
}
设置pdf版本
通过PdfWriter 的 setPdfVersion 方法来设置我们pdf的版本号
public class HelloWorldVersion_1_7 {
public static final String RESULT = "src/main/resources/hello_1_7.pdf";
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
// Creating a PDF 1.7 document
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
writer.setPdfVersion(PdfWriter.VERSION_1_7);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello World!"));
// step 5
document.close();
}
}
添加内容
添加内容也有两个方法
- 往Document类中添加high-level的对象
- 直接用PdfWriter实例添加比较low-level的数据。
public class HelloWorldDirect {
public static final String RESULT = "src/main/resources/hello_direct.pdf";
public static void main(String[] args)
throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
PdfContentByte canvas = writer.getDirectContentUnder();
writer.setCompressionLevel(0);
canvas.saveState(); // q
canvas.beginText(); // BT
canvas.moveText(36, 788); // 36 788 Td
canvas.setFontAndSize(BaseFont.createFont(), 12); // /F1 12 Tf
canvas.showText("Hello World"); // (Hello World)Tj
canvas.endText(); // ET
canvas.restoreState(); // Q
// step 5
document.close();
}
}
和以前代码不同的是:我们将生成的PdfWriter实例保存到局部变量writer中。因为后续要通过此writer来获取canvas画线画图。代码中通过设置CompressionLevel属性为0可以避免对输出流的压缩,我们也可以通过记事本来查看pdf的语法语句。以上canvas的每个方法后面的注释对应具体的pdf语法,大家用记事本打开就可以看到。
压缩多个pdf文件
通过ZipEntry 将多个pdf压缩成一个压缩文件
public class HelloZip {
public static final String RESULT = "src/main/resources/hello.zip";
public static void main(String[] args)
throws DocumentException, IOException {
// creating a zip file with different PDF documents
ZipOutputStream zip =
new ZipOutputStream(new FileOutputStream(RESULT));
for (int i = 1; i <= 3; i++) {
ZipEntry entry = new ZipEntry("hello_" + i + ".pdf");
zip.putNextEntry(entry);
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, zip);
writer.setCloseStream(false);
// step 3
document.open();
// step 4
document.add(new Paragraph("Hello " + i));
// step 5
document.close();
zip.closeEntry();
}
zip.close();
}
}
添加新页
document.newPage();
添加水印
文字水印
public class PdfWaterMark {
public static final String RESULT = "src/main/resources/font_water_mark.pdf";
public static void main(String[] args) throws FileNotFoundException, DocumentException {
Document document = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// 打开文档
document.open();
// 加入水印
PdfContentByte waterMar = pdfWriter.getDirectContentUnder();
// 开始设置水印
waterMar.beginText();
// 设置水印透明度
PdfGState gs = new PdfGState();
// 设置填充字体不透明度为0.4f
gs.setFillOpacity(0.4f);
try {
// 设置水印字体参数及大小 (字体参数,字体编码格式,是否将字体信息嵌入到pdf中(一般不需要嵌入),字体大小)
waterMar.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 60);
// 设置透明度
waterMar.setGState(gs);
// 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
waterMar.showTextAligned(Element.ALIGN_RIGHT, "www.newland.com", 500, 430, 45);
// 设置水印颜色
waterMar.setColorFill(BaseColor.GRAY);
//结束设置
waterMar.endText();
waterMar.stroke();
} catch (IOException e) {
e.printStackTrace();
}
// 加入文档内容
document.add(new Paragraph("my first pdf demo"));
// 关闭文档
document.close();
pdfWriter.close();
}
}
图片水印
public class PdfWaterMark {
public static final String RESULT = "src/main/resources/img_water_mark.pdf";
public static void main(String[] args) throws FileNotFoundException, DocumentException {
Document document = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// 打开文档
document.open();
// 加入水印
PdfContentByte waterMar = pdfWriter.getDirectContentUnder();
// 开始设置水印
waterMar.beginText();
// 设置水印透明度
PdfGState gs = new PdfGState();
// 设置填充字体不透明度为0.4f
gs.setFillOpacity(0.4f);
try {
Image image = Image.getInstance("D:\\Folder\\image\\logo.png");
// 设置坐标 绝对位置 X Y
image.setAbsolutePosition(200, 300);
// 设置旋转弧度
image.setRotation(30);// 旋转 弧度
// 设置旋转角度
image.setRotationDegrees(45);// 旋转 角度
// 设置等比缩放
image.scalePercent(30);// 依照比例缩放
// image.scaleAbsolute(200,100);//自定义大小
// 设置透明度
waterMar.setGState(gs);
// 添加水印图片
waterMar.addImage(image);
// 设置透明度
waterMar.setGState(gs);
//结束设置
waterMar.endText();
waterMar.stroke();
} catch (IOException e) {
e.printStackTrace();
}
// 加入文档内容
document.add(new Paragraph("hello world"));
// 关闭文档
document.close();
pdfWriter.close();
}
}
给已经存在的pdf添加文字水印
/**
* 已有的pdf文件添加水印
* @param inputFile:要加水印的源文件的路径
* @param outputFile:加水印后文件的输出路径
* @param waterMarkName:要加的水印名
*/
public static void waterMark(String inputFile,String outputFile, String waterMarkName) {
try {
PdfReader reader = new PdfReader(inputFile);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
//改透明度
gs.setFillOpacity(0.5f);
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
JLabel label = new JLabel();
label.setText(waterMarkName);
PdfContentByte under;
// 添加一个水印
for (int i = 1; i < total; i++) {
// 在内容上方加水印
under = stamper.getOverContent(i);
//在内容下方加水印
//under = stamper.getUnderContent(i);
gs.setFillOpacity(0.5f);
under.setGState(gs);
under.beginText();
//改变颜色
under.setColorFill(BaseColor.LIGHT_GRAY);
//改水印文字大小
under.setFontAndSize(base, 100);
under.setTextMatrix(70, 200);
//后3个参数,x坐标,y坐标,角度
under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, 300, 350, 55);
under.endText();
}
stamper.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
给已经存在的pdf添加图片水印
/**
* @param inputFile:要加水印的源文件的路径
* @param outputFile:加水印后文件的输出路径
* @param pocturePath: 图片的位置
*/
public static void pictureWaterMark(String inputFile, String outputFile, String pocturePath) {
try {
PdfReader reader = new PdfReader(inputFile);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
PdfGState gs = new PdfGState();
//设置透明度
gs.setFillOpacity(0.3f);
gs.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages() + 1;
PdfContentByte waterMar;
// 添加一个水印
for (int i = 1; i < total; i++) {
// 在内容上方加水印
waterMar = stamper.getOverContent(i);
//在内容下方加水印
//under = stamper.getUnderContent(i);
waterMar.setGState(gs);
waterMar.beginText();
Image image = Image.getInstance(pocturePath);
// 设置坐标 绝对位置 X Y
image.setAbsolutePosition(150, 250);
// 设置旋转弧度
image.setRotation(30);// 旋转 弧度
// 设置旋转角度
image.setRotationDegrees(45);// 旋转 角度
// 设置等比缩放
image.scalePercent(30);// 依照比例缩放
// image.scaleAbsolute(200,100);//自定义大小
// 添加水印图片
waterMar.addImage(image);
// 设置透明度
waterMar.setGState(gs);
//结束设置
waterMar.endText();
waterMar.stroke();
}
stamper.close();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
pdf加密
首先要说明的是,itext中对pdf文档的加密包括两部分,第一部分是用户密码,第二部分是所有者密码。这两部分可以简单的理解为管理员密码和用户密码,因此我们在设置这两个密码的权限的时候,往往会将所有者密码的权限级别设置的更高,而用户密码权限往往是“只读”。
在之前的基础上添加新的Maven依赖
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
public class PdfPassword {
public static final String RESULT = "src/main/resources/password.pdf";
public static void main(String[] args) throws FileNotFoundException,
DocumentException {
//实现A4纸页面 并且横向显示(不设置则为纵向)
Document document = new Document(PageSize.A4.rotate());
PdfWriter pdfWriter = PdfWriter.getInstance(document,new FileOutputStream(RESULT));
// 设置用户密码, 所有者密码,用户权限,所有者权限
pdfWriter.setEncryption("userpassword".getBytes(), "ownerPassword".getBytes(), PdfWriter.ALLOW_COPY, PdfWriter.ENCRYPTION_AES_128);
// 打开文档
document.open();
// 加入文档内容
document.add(new Paragraph("hello world"));
// 关闭文档
document.close();
pdfWriter.close();
}
}
-
然后我们打开我们的pdf文档,会弹出一个让你输入密码的对话框,我们先用“userpassword”这个用户密码去打开。然后再查看文档的属性,具体如下:
-
我们可以看到,我们是无法对现在的这个pdf进行打印和修改的。接下来,我们重新打开这个pdf。用“ownerPassword”这个密码取打开。然后再查看文档的属性,具体如下:
权限参数
PdfWriter.ALLOW_MODIFY_CONTENTS
允许打印,编辑,复制,签名 加密级别:40-bit-RC4
PdfWriter.ALLOW_COPY
允许复制,签名 不允许打印,编辑 加密级别:40-bit-RC
PdfWriter.ALLOW_MODIFY_ANNOTATIONS
允许打印,编辑,复制,签名 加密级别:40-bit-RC4
PdfWriter.ALLOW_FILL_IN
允许打印,编辑,复制,签名 加密级别:40-bit-RC4
PdfWriter.ALLOW_SCREENREADERS
允许打印,编辑,复制,签名 加密级别:40-bit-RC4
PdfWriter.ALLOW_ASSEMBLY
允许打印,编辑,复制,签名 加密级别:40-bit-RC4
PdfWriter.EMBEDDED_FILES_ONLY
允许打印,编辑,复制,签名 加密级别:40-bit-RC4
PdfWriter.DO_NOT_ENCRYPT_METADATA
允许打印,编辑,复制,签名 加密级别:40-bit-RC4
PdfWriter.ENCRYPTION_AES_256
允许打印,编辑,复制,签名 加密级别:256-bit-AES
PdfWriter.ENCRYPTION_AES_128
允许打印,编辑,复制,签名 加密级别:128-bit-AES
PdfWriter.STANDARD_ENCRYPTION_128
允许打印,编辑,复制,签名 加密级别:128-bit-RC4
PdfWriter.STANDARD_ENCRYPTION_40
允许打印,编辑,复制,签名 加密级别:40-bit-RC4
使用iText的基本构建快
现在我们将重点集中到第四步:添加内容。这里说的添加内容都是通过Document.Add()方法调用,也就是通过一些high-level的对象实现内容的添加。这一节如标题要介绍Chunk、Phrase、Paragraph和List对象的属性和使用。Document的Add方法接受一个IElement的接口,我们先来看下实现此接口的UML图:
Chunk 对象
Chunk类是可以添加到Document中最小的文本片段。Chunk类中包含一个StringBuilder对象,其代表了有相同的字体,字体大小,字体颜色和字体格式的文本,这些属性定义在Chunk类中Font对象中。其它的属性如背景色(background),text rise(用来模拟下标和上标)还有underline(用来模拟文本的下划线或者删除线)都定义在其它一系列的属性中,这些属性都可以通过settter 方法进行设置.
public class CountryChunks {
public static final String RESULT = "src/main/resources/country_chunks.pdf";
public static void main(String[] args)
throws IOException, DocumentException, SQLException {
new CountryChunks().createPdf(RESULT);
}
public void createPdf(String filename)
throws IOException, DocumentException, SQLException {
// step 1
Document document = new Document();
// step 2
PdfWriter.getInstance(document, new FileOutputStream(filename))
.setInitialLeading(16);
// step 3
document.open();
// step 4
// add a country to the document as a Chunk
document.add(new Chunk("China"));
document.add(new Chunk(" "));
Font font = new Font(Font.FontFamily.HELVETICA, 6, Font.BOLD, BaseColor.WHITE);
Chunk id = new Chunk("cn", font);
// with a background color
id.setBackground(BaseColor.BLACK, 1f, 0.5f, 1f, 1.5f);
// and a text rise
id.setTextRise(6);
document.add(id);
document.add(Chunk.NEWLINE);//换行 NEWLINE = new Chunk("\n");
// step 5
document.close();
}
}
行间距: LEADING
使用Chunk类要注意的是其不知道两行之间的行间距(Leading),这就是为什么在代码中要设置InitialLeading属性的原因。大家可以试着将其去掉然后再看下重新生存的pdf文档:你会发现所有的文本都写在同一行上。
SetTextRise
SetTextRise方法的参数表示的是离这一行的基准线(baseline)的距离,如果为正数就会模拟上标,负数就会模拟为下标。
Phrase 对象
Chunk类在iText是最小的原子文本,而Phrase类被定义为 “a string of word”,因此Phrase是一个组合的对象。转换为java和iText来说,phrase就是包含了Chunk类的一个ArraryList。
Font bul = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.BOLD | Font.UNDERLINE);
Font normal = new Font(Font.FontFamily.TIMES_ROMAN, 12);
Phrase director = new Phrase();
director.Add(new Chunk("China", bul));
director.Add(new Chunk(",", bul));
director.Add(new Chunk("id", normal));
document.add(director);
Paragraph 对象
可以将Phrase和Paragraph类比HTML中的span和div。如果在前一个例子中用Paragraph代替Phrase,就没有必要添加document.Add(Chunk.NEWLINE)。
Paragraph继承Phrase类,因此我们在创建Paragraph类时和创建Phrase完全一致,不过Paragraph拥有更多的属性设置:定义文本的对齐方式、不同的缩进和设置前后的空间大小。
html转为pdf
这里需要说明一个情况,如果项目中不引入字体文件,那么生成的pdf将不会显示文字(因为生产环境的服务器不会有任何字体文件,而本地运行的话,会自动去电脑中的字体文件库中去寻找字体文件),因此,如果是需要发布的项目,务必将字体文件放到项目中,然后进行使用。
引入Maven依赖
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>认识table表标签</title>
<style type="text/css">
/*解决html转pdf文件中文不显示的问题*/
body {
font-family: SimSun;
}
/*设定纸张大小*/
/* A4纸 */
/* @page{size:210mm*297mm} */
@page{size:a4}
p {
color: red;
}
</style>
</head>
<body>
<table border="1px">
<caption>我的标题</caption>
<tbody>
<tr>
<th>班级</th>
<th>学生数</th>
<th>平均成绩</th>
<th>班级</th>
<th>学生数</th>
<th>平均成绩</th>
<th>班级</th>
<th>学生数</th>
<th>平均成绩</th>
</tr>
<tr>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
</tr>
<tr>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
</tr>
<tr>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
<td>一班</td>
<td>30</td>
<td>89</td>
</tr>
</tbody>
</table>
<p>
《侠客行》<br/>
年代: 唐 作者: 李白<br/>
赵客缦胡缨,吴钩霜雪明。银鞍照白马,飒沓如流星。
十步杀一人,千里不留行。事了拂衣去,深藏身与名。
闲过信陵饮,脱剑膝前横。将炙啖朱亥,持觞劝侯嬴。
三杯吐然诺,五岳倒为轻。眼花耳热后,意气素霓生。
救赵挥金槌,邯郸先震惊。千秋二壮士,煊赫大梁城。
纵死侠骨香,不惭世上英。谁能书閤下,白首太玄经。
</p>
</body>
</html>
PdfUtil.java
public class PdfUtil {
/**
* @param htmlFile html文件存储路径
* @param pdfFile 生成的pdf文件存储路径
* @param chineseFontPath 中文字体存储路径
*/
public static void html2pdf(String htmlFile, String pdfFile, String chineseFontPath){
// step 1
String url;
OutputStream os = null;
try {
url = new File(htmlFile).toURI().toURL().toString();
os = new FileOutputStream(pdfFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
// 解决中文不显示问题
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont(chineseFontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(os);
} catch (Exception e) {
} finally {
if (os != null) {
try {
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
try {
//获取项目路径
String projectPath = System.getProperty("user.dir");
//html文件路径
String htmlFilePath = projectPath + "/src/main/resources/index.html";
// 中文字体存储路径
String chineseFontPath = projectPath +"/src/main/resources/Fonts/simsun.ttc";
// html转pdf
html2pdf(htmlFilePath, projectPath + "/src/main/resources/html2pdf.pdf", chineseFontPath);
System.out.println("转换成功!");
} catch (Exception e) {
System.out.println("转换失败!");
e.printStackTrace();
}
}
}
iText转html为pdf遇到的问题
-
中文不显示
原因: iText默认不支持中文
解决方法: 引入中文字体 (本机字体文件库C:\Windows\Fonts中下载上传到项目中)
需要注意的是在java代码中设置好中文字体后,还需要在html引用该字体,否则不会起效果。
// 解决中文不显示问题 ITextFontResolver fontResolver = renderer.getFontResolver(); fontResolver.addFont(chineseFontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
/*解决html转pdf文件中文不显示的问题*/ body { font-family: SimSun; }
-
css不起作用
原因: css文件使用的是相对路径
解决方法: 将相对路径改为绝对路径或者把css样式写在html内部.
-
html内容转为pdf后内容不全
解决方法: 在html中设定纸张大小
/*设定纸张大小*/ /* A4纸 */ /* @page{size:210mm*297mm} */ @page{size:a4}
iText转html为pdf遇到的问题
-
中文不显示
原因: iText默认不支持中文
解决方法: 引入中文字体 (本机字体文件库C:\Windows\Fonts中下载上传到项目中)
需要注意的是在java代码中设置好中文字体后,还需要在html引用该字体,否则不会起效果。
// 解决中文不显示问题 ITextFontResolver fontResolver = renderer.getFontResolver(); fontResolver.addFont(chineseFontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
/*解决html转pdf文件中文不显示的问题*/ body { font-family: SimSun; }
-
css不起作用
原因: css文件使用的是相对路径
解决方法: 将相对路径改为绝对路径或者把css样式写在html内部.
-
html内容转为pdf后内容不全
解决方法: 在html中设定纸张大小
/*设定纸张大小*/ /* A4纸 */ /* @page{size:210mm*297mm} */ @page{size:a4}
推荐博客:https://www.cnblogs.com/julyluo/archive/2012/07/29/2613822.html
推荐博客:https://www.cnblogs.com/liaojie970/p/7132475.html