pom.xml文件配置===

<!-- 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文档:
一、主要步骤(5个):

1.新建document对象,可通过一下三种任意一种
Document document =new Document(); // 默认页面大小是A4
Document document =new Document(PageSize.A4); // 指定页面大小为A4
Document document =new Document(PageSize.A4,50,50,30,20); // 指定页面大小为A4,且自定义页边距(marginLeft、marginRight、marginTop、marginBottom)
其中页面大小PageSize也可自定义大小,例:new Document(new Rectangle(400, 500));

2.建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。
创建 PdfWriter 对象 第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径
PdfWriter writer =PdfWriter.getInstance(document,new FileOutputStream(filePath));

3.打开文档
写入数据之前要打开文档
document.open();

4.向文档中添加内容
document.add();

5.关闭文档
document.close();

二、字体

新建一个字体,iText的方法
BaseFont bfChinese;
bfChinese=BaseFont.createFont("STSongStd-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);//jar包
bfChinese=BaseFont.createFont("C:/Windows/Fonts/msyh.ttf",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); //系统字体,其实5.0版以后的iText加入字体还是很方便的。
STSongStd-Light 是字体,在jar 中以property为后缀
UniGB-UCS2-H 是编码,在jar 中以cmap为后缀
H 代表文字版式是横版,相应的 V 代表竖版

字体设置
参数一:新建好的字体;参数二:字体大小,参数三:字体样式,多个样式用“|”分隔
Font topfont = new Font(bfChinese,14,Font.BOLD);
Font textfont =new Font(bfChinese,10,,Font.BOLD|Font.UNDERLINE);

三、添加文本的对象:块、短句和段落

Chunk:块(Chunk)是能被添加到文档的文本的最小单位。
Phrase:短句(Phrase)是一系列以特定间距(两行之间的距离)作为参数的块。
Paragraph:段落是一系列块和(或)短句。同短句一样,段落有确定的间距。用户还可以指定缩排;在边和(或)右边保留一定空白,段落可以左对齐、右对齐和居中对齐。添加到文档中的每一个段落将自动另起一行。

四、步骤2书写器创建之后,步骤3文档打开之前
以下项只可在文档关闭状态执行 ,包括水印、页眉、页脚

水印
Watermark内部类,需要继承 PdfPageEventHelper类
writer.setPageEvent(new Watermark());

页眉/页脚
iText5中并没有之前版本HeaderFooter对象设置页眉和页脚,可以利用PdfPageEvent来完成页眉页脚的设置工作。
PdfPageEvent提供了几个pdf在创建时的事件,页眉页脚就是在每页加载完写入的。
每一页加个页码还是很简单的,但是总页码就麻烦了,iText是流模式的写入内容,只有写到最后,才能知道有多少页,那么显示总页数就麻烦了,不过麻烦不代表不可能。
其实iText仅在调用释放模板方法后才将PdfTemplate写入到OutputStream中,否则对象将一直保存在内存中,直到关闭文档。
所以我们可以在最后关闭文档前,使用PdfTemplate写入总页码。可以理解成先写个占位符,然后统一替换。

五、设置文档属性  (与文档是否打开没有关联)

document.addTitle("Title@PDF-Java");// 标题
document.addAuthor("Author@umiz");// 作者
document.addSubject("Subject@iText pdf sample");// 主题
document.addKeywords("Keywords@iTextpdf");// 关键字
document.addCreator("Creator@umiz`s");// 创建者

六、文档内容

段落Paragraph
Paragraph pt=new Paragraph(name,headfont);//设置字体样式
pt.setAlignment(1);//设置文字居中 0靠左   1,居中     2,靠右
pt.setIndentationLeft(12);// 左缩进  
pt.setIndentationRight(12);// 右缩进  
pt.setFirstLineIndent(24);// 首行缩进 
paragraph.setLeading(20f); //行间距
paragraph.setSpacingBefore(5f); //设置段落上空白
paragraph.setSpacingAfter(10f); //设置段落下空白

表格table
Table table =new Table(3);//括号参数表示列
int width[] = {10,45,45};//设置每列宽度比例   
table.setWidths(width);   
table.setWidth(95);//占页面宽度比例
table.setAlignment(Element.ALIGN_CENTER);//居中    
table.setAutoFillEmptyCells(true);//自动填满       
table.setBorderWidth((float)0.1);//表格边框线条宽度    
table.setPadding(1);//边距:单元格的边线与单元格内容的边距  
table.setSpacing(0);//间距:单元格与单元格之间的距离
table.addCell(new Paragraph("name"),textfont));//添加单元格内容
table.endHeaders();//每页都会显示表头

单元格内容样式cell  
Cell cell=new Cell(new Paragraph("序号",keyfont));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);//水平居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //垂直居中   
table.addCell(cell);

表格嵌套 
  最外层表格
PdfPTable table =new PdfPTable(3);
table.setTotalWidth(300);
table.setLockedWidth(true);

PdfPCell cell;
cell =new PdfPCell(new Phrase("Table 5"));
cell.setColspan(3);
cell.setBorderWidth(0);//设置表格的边框宽度为0
table.addCell(cell);

嵌套表格
PdfPTable celltable =new PdfPTable(2);
cell =new PdfPCell(celltable);
cell.setRowspan(2);
cell.setBorderWidth(1);//设置表格的边框宽度为1
cell.setPadding(10);//设置表格与上一个表格的填充为10
table.addCell(cell);

直线  
Paragraph p1 =new Paragraph();  
p1.add(new Chunk(new LineSeparator()));   
doc.add(p1);

点线  
Paragraph p2 =new Paragraph();  
p2.add(new Chunk(new DottedLineSeparator()));

超链接
Anchor anchor =new Anchor("this is anchor");

定位
点击后,跳到topline的位置
Anchor gotop =new Anchor("go top");
gotop.setReference("#us");

添加图片
Image image =Image.getInstance(imgPath);
image.setAlignment(Image.ALIGN_CENTER);
image.scalePercent(40);//依照比例缩放

七、一个简单的demo:后台代码======

package com.soco.erp;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.DottedLineSeparator;
import com.itextpdf.text.pdf.draw.LineSeparator;

import java.io.File;
import java.io.FileOutputStream;

public class PdfReport {

// main测试
public static void main(String[] args) throws Exception {
try {
// 1.新建document对象
Document document = new Document(PageSize.A4);// 建立一个Document对象

// 2.建立一个书写器(Writer)与document对象关联
File file = new File("D:\\PDFDemo.pdf");
file.createNewFile();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
writer.setPageEvent(new Watermark("HELLO ITEXTPDF"));// 水印
writer.setPageEvent(new MyHeaderFooter());// 页眉/页脚

// 3.打开文档
document.open();
document.addTitle("Title@PDF-Java");// 标题
document.addAuthor("Author@umiz");// 作者
document.addSubject("Subject@iText pdf sample");// 主题
document.addKeywords("Keywords@iTextpdf");// 关键字
document.addCreator("Creator@umiz`s");// 创建者

// 4.向文档中添加内容
new PdfReport().generatePDF(document);

// 5.关闭文档
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}

// 定义全局的字体静态变量
private static Font titlefont;
private static Font headfont;
private static Font keyfont;
private static Font textfont;
// 最大宽度
private static int maxWidth = 520;
// 静态代码块
static {
try {
// 不同字体(这里定义为同一种字体:包含不同字号、不同style)
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
titlefont = new Font(bfChinese, 16, Font.BOLD);
headfont = new Font(bfChinese, 14, Font.BOLD);
keyfont = new Font(bfChinese, 10, Font.BOLD);
textfont = new Font(bfChinese, 10, Font.NORMAL);

} catch (Exception e) {
e.printStackTrace();
}
}

// 生成PDF文件
public void generatePDF(Document document) throws Exception {

// 段落
Paragraph paragraph = new Paragraph("美好的一天从早起开始!", titlefont);
paragraph.setAlignment(1); //设置文字居中 0靠左 1,居中 2,靠右
paragraph.setIndentationLeft(12); //设置左缩进
paragraph.setIndentationRight(12); //设置右缩进
paragraph.setFirstLineIndent(24); //设置首行缩进
paragraph.setLeading(20f); //行间距
paragraph.setSpacingBefore(5f); //设置段落上空白
paragraph.setSpacingAfter(10f); //设置段落下空白

// 直线
Paragraph p1 = new Paragraph();
p1.add(new Chunk(new LineSeparator()));

// 点线
Paragraph p2 = new Paragraph();
p2.add(new Chunk(new DottedLineSeparator()));

// 超链接
Anchor anchor = new Anchor("baidu");
anchor.setReference("www.baidu.com");

// 定位
Anchor gotoP = new Anchor("goto");
gotoP.setReference("#top");

// 添加图片
Image image = Image.getInstance("https://img-blog.csdn.net/20180801174617455?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzg0ODcxMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70");
image.setAlignment(Image.ALIGN_CENTER);
image.scalePercent(40); //依照比例缩放

// 表格
PdfPTable table = createTable(new float[] { 40, 120, 120, 120, 80, 80 });
table.addCell(createCell("美好的一天", headfont, Element.ALIGN_LEFT, 6, false));
table.addCell(createCell("早上9:00", keyfont, Element.ALIGN_CENTER));
table.addCell(createCell("中午11:00", keyfont, Element.ALIGN_CENTER));
table.addCell(createCell("中午13:00", keyfont, Element.ALIGN_CENTER));
table.addCell(createCell("下午15:00", keyfont, Element.ALIGN_CENTER));
table.addCell(createCell("下午17:00", keyfont, Element.ALIGN_CENTER));
table.addCell(createCell("晚上19:00", keyfont, Element.ALIGN_CENTER));
Integer totalQuantity = 0;
for (int i = 0; i < 5; i++) {
table.addCell(createCell("起床", textfont));
table.addCell(createCell("吃午饭", textfont));
table.addCell(createCell("午休", textfont));
table.addCell(createCell("下午茶", textfont));
table.addCell(createCell("回家", textfont));
table.addCell(createCell("吃晚饭", textfont));
totalQuantity ++;
}
table.addCell(createCell("总计", keyfont));
table.addCell(createCell("", textfont));
table.addCell(createCell("", textfont));
table.addCell(createCell("", textfont));
table.addCell(createCell(String.valueOf(totalQuantity) + "件事", textfont));
table.addCell(createCell("", textfont));

document.add(paragraph);
document.add(anchor);
document.add(p2);
document.add(gotoP);
document.add(p1);
document.add(table);
document.add(image);
}


/**------------------------创建表格单元格的方法start----------------------------*/
/**
* 创建单元格(指定字体)
* @param value
* @param font
* @return
*/
public PdfPCell createCell(String value, Font font) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 创建单元格(指定字体、水平..)
* @param value
* @param font
* @param align
* @return
*/
public PdfPCell createCell(String value, Font font, int align) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并)
* @param value
* @param font
* @param align
* @param colspan
* @return
*/
public PdfPCell createCell(String value, Font font, int align, int colspan) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并、设置单元格内边距)
* @param value
* @param font
* @param align
* @param colspan
* @param boderFlag
* @return
*/
public PdfPCell createCell(String value, Font font, int align, int colspan, boolean boderFlag) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
cell.setPadding(3.0f);
if (!boderFlag) {
cell.setBorder(0);
cell.setPaddingTop(15.0f);
cell.setPaddingBottom(8.0f);
} else if (boderFlag) {
cell.setBorder(0);
cell.setPaddingTop(0.0f);
cell.setPaddingBottom(15.0f);
}
return cell;
}
/**
* 创建单元格(指定字体、水平..、边框宽度:0表示无边框、内边距)
* @param value
* @param font
* @param align
* @param borderWidth
* @param paddingSize
* @param flag
* @return
*/
public PdfPCell createCell(String value, Font font, int align, float[] borderWidth, float[] paddingSize, boolean flag) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setPhrase(new Phrase(value, font));
cell.setBorderWidthLeft(borderWidth[0]);
cell.setBorderWidthRight(borderWidth[1]);
cell.setBorderWidthTop(borderWidth[2]);
cell.setBorderWidthBottom(borderWidth[3]);
cell.setPaddingTop(paddingSize[0]);
cell.setPaddingBottom(paddingSize[1]);
if (flag) {
cell.setColspan(2);
}
return cell;
}
/**------------------------创建表格单元格的方法end----------------------------*/


/**--------------------------创建表格的方法start------------------- ---------*/
/**
* 创建默认列宽,指定列数、水平(居中、右、左)的表格
* @param colNumber
* @param align
* @return
*/
public PdfPTable createTable(int colNumber, int align) {
PdfPTable table = new PdfPTable(colNumber);
try {
table.setTotalWidth(maxWidth);
table.setLockedWidth(true);
table.setHorizontalAlignment(align);
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
/**
* 创建指定列宽、列数的表格
* @param widths
* @return
*/
public PdfPTable createTable(float[] widths) {
PdfPTable table = new PdfPTable(widths);
try {
table.setTotalWidth(maxWidth);
table.setLockedWidth(true);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
/**
* 创建空白的表格
* @return
*/
public PdfPTable createBlankTable() {
PdfPTable table = new PdfPTable(1);
table.getDefaultCell().setBorder(0);
table.addCell(createCell("", keyfont));
table.setSpacingAfter(20.0f);
table.setSpacingBefore(20.0f);
return table;
}
/**--------------------------创建表格的方法end------------------- ---------*/


}

页眉/页脚的定义实现类:

package com.soco.erp;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.IOException;

public class MyHeaderFooter extends PdfPageEventHelper {
// 总页数
PdfTemplate totalPage;
Font hfFont;
{
try {
hfFont = new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 8, Font.NORMAL);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

// 打开文档时,创建一个总页数的模版
public void onOpenDocument(PdfWriter writer, Document document) {
PdfContentByte cb =writer.getDirectContent();
totalPage = cb.createTemplate(30, 16);
}
// 一页加载完成触发,写入页眉和页脚
public void onEndPage(PdfWriter writer, Document document) {
PdfPTable table = new PdfPTable(3);
try {
table.setTotalWidth(PageSize.A4.getWidth() - 100);
table.setWidths(new int[] { 24, 24, 3});
table.setLockedWidth(true);
table.getDefaultCell().setFixedHeight(-10);
table.getDefaultCell().setBorder(Rectangle.BOTTOM);

table.addCell(new Paragraph("我是页眉/页脚", hfFont));// 可以直接使用addCell(str),不过不能指定字体,中文无法显示
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
table.addCell(new Paragraph("第" + writer.getPageNumber() + "页/", hfFont));
// 总页数
PdfPCell cell = new PdfPCell(Image.getInstance(totalPage));
cell.setBorder(Rectangle.BOTTOM);
table.addCell(cell);
// 将页眉写到document中,位置可以指定,指定到下面就是页脚
table.writeSelectedRows(0, -1, 50,PageSize.A4.getHeight() - 20, writer.getDirectContent());
} catch (Exception de) {
throw new ExceptionConverter(de);
}
}

// 全部完成后,将总页数的pdf模版写到指定位置
public void onCloseDocument(PdfWriter writer,Document document) {
String text = "总" + (writer.getPageNumber()) + "页";
ColumnText.showTextAligned(totalPage, Element.ALIGN_LEFT, new Paragraph(text,hfFont), 2, 2, 0);
}

}

加水印的实现类:

package com.soco.erp;

import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;

public class Watermark extends PdfPageEventHelper {
Font FONT = new Font(Font.FontFamily.HELVETICA, 30, Font.BOLD, new GrayColor(0.95f));
private String waterCont;//水印内容
public Watermark() {

}
public Watermark(String waterCont) {
this.waterCont = waterCont;
}

@Override
public void onEndPage(PdfWriter writer, Document document) {
for(int i=0 ; i<5; i++) {
for(int j=0; j<5; j++) {
ColumnText.showTextAligned(writer.getDirectContentUnder(),
Element.ALIGN_CENTER,
new Phrase(this.waterCont == null ? "HELLO WORLD" : this.waterCont, FONT),
(50.5f+i*350),
(40.0f+j*150),
writer.getPageNumber() % 2 == 1 ? 45 : -45);
}
}
}
}

springMVC生成pdf文件的更多相关文章

  1. linux下编译bib、tex生成pdf文件

    实验: 在linux环境下,编译(英文)*.bib和*.tex文件,生成pdf文件. 环境: fedora 20(uname -a : Linux localhost.localdomain 3.19 ...

  2. ThinkPHP3.2.3扩展之生成PDF文件(MPDF)

    目前是PHP生成PDF文件最好的插件了,今天介绍下在ThinkPHP3.2.3里如何使用. 先安照路径放好如图. 下面是使用方法 public function pdf(){ //引入类库 Vendo ...

  3. [轉載]史上最强php生成pdf文件,html转pdf文件方法

    之前有个客户需要把一些html页面生成pdf文件,然后我就找一些用php把html页面围成pdf文件的类.方法是可谓是找了很多很多,什么html2pdf,pdflib,FPDF这些都试过了,但是都没有 ...

  4. asp.net生成PDF文件 (1)

    asp.net生成PDF文件 (1) 这个是例子是网上淘来的,哈哈,很有用的! 首先要到网上下载itextsharp.dll,然后添加引用,主程序如下: 1 2 3 4 5 6 7 8 9 10 11 ...

  5. 怎么用PHP在HTML中生成PDF文件

    原文:Generate PDF from html using PHP 译文:使用PHP在html中生成PDF 译者:dwqs 利用PHP编码生成PDF文件是一个非常耗时的工作.在早期,开发者使用PH ...

  6. JAVA生成PDF文件

    生成PDF文件是主要应用的是ITEXT插件 import java.awt.Color; import java.io.File; import java.io.FileOutputStream; i ...

  7. .NET生成PDF文件

    C#未借助第三方组件,自己封装通用类,生成PDF文件. 调用方式: //路径 string path = @"C:\yuannwu22.pdf"; //内容 string strC ...

  8. 史上最强php生成pdf文件,html转pdf文件方法

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  9. java调用wkhtmltopdf生成pdf文件,美观,省事

    最近项目需要导出企业风险报告,文件格式为pdf,于是搜了一大批文章都是什么Jasper Report,iText ,flying sauser ,都尝试了一遍,感觉不是我想要的效果, 需要自己调整好多 ...

随机推荐

  1. 【鸿蒙开发板试用报告】用OLED板实现FlappyBird小游戏(中)

    小伙伴们久等了,在上一篇<[开发板试用报告]用OLED板实现FlappyBird小游戏(上)>中,我们本着拿来主义的原则,成功的让小鸟在OLED屏幕上自由飞翔起来,下面我们将加入按钮交互功 ...

  2. 新手上路之如何选择Java版本

    @ 目录 LTS与非LTS LTS 非LTS Java CPU与PSU Java SE.Java EE.Java ME的区别 Java SE Java EE Java ME 每一次JDK上新总有一群人 ...

  3. python 爬虫 汽车之家车辆参数反爬

    水平有限,仅供参考. 如图所示,汽车之家的车辆详情里的数据做了反爬对策,数据被CSS伪类替换. 观察 Sources 发现数据就在当前页面. 发现若干条进行CSS替换的js 继续深入此JS 知道了数据 ...

  4. 【NOIP2017提高A组模拟9.17】组合数问题

    [NOIP2017提高A组模拟9.17]组合数问题 题目 Description 定义"组合数"S(n,m)代表将n 个不同的元素拆分成m 个非空集合的方案数. 举个例子,将{1,2,3}拆分成2 个 ...

  5. JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠

    JZOJ [NOIP2017提高A组模拟9.14]捕老鼠 题目 Description 为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠.于是,猫被农夫约派去捕 ...

  6. CPU实现原子操作的原理

    586之前的CPU, 会通过LOCK锁总线的形式来实现原子操作. 686开始则提供了存储一致性(Cache coherence),  这是多处理的基础, 也是原子操作的基础. 1. 存储的粒度 存储的 ...

  7. vue-父子组件传参以及无限级评论

    vue父子组件的使用 <template> <div> <zi :data="data" /> </div> </templa ...

  8. RabbitMQ Go客户端教程5——topic

    本文翻译自RabbitMQ官网的Go语言客户端系列教程,本文首发于我的个人博客:liwenzhou.com,教程共分为六篇,本文是第五篇--topic. 这些教程涵盖了使用RabbitMQ创建消息传递 ...

  9. Flutter——Dart Extension扩展方法的使用

    dart的extension方法可以给已经存在的类添加新的函数,通过extension我们可以封装一些常用方法,提高开发效率. 例一:扩展String 给string添加一个log打印方法 exten ...

  10. PyQt学习随笔:Model和View之间的数据互动过程

    在<PyQt学习随笔:Qt中tem Views(Model-Based)和Item Widgets(Item-Based)控件的用途和关系>中介绍了,Model用于存储数据,View用于展 ...