1.依赖版本
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
2.设置页眉页脚
package com.tedu.util;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.IOException;
/**
* 设置页眉页脚
* @author syl
*/
public class HeaderFooter 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();
}
}
/**
* 打开文档时,创建一个总页数的模版
* @param writer
* @param document
*/
@Override
public void onOpenDocument(PdfWriter writer, Document document) {
PdfContentByte cb =writer.getDirectContent();
totalPage = cb.createTemplate(30, 16);
}
/**
* 一页加载完成触发,写入页眉和页脚
* @param writer
* @param document
*/
@Override
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);
// 可以直接使用addCell(str),不过不能指定字体,中文无法显示
table.addCell(new Paragraph("页眉/页脚", hfFont));
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模版写到指定位置
* @param writer
* @param document
*/
@Override
public void onCloseDocument(PdfWriter writer, Document document) {
String text = "总" + (writer.getPageNumber()) + "页";
ColumnText.showTextAligned(totalPage, Element.ALIGN_LEFT, new Paragraph(text,hfFont), 2, 2, 0);
}
}
3.设置水印
package com.tedu.util;
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;
/**
* 水印
* @author syl
*/
public class Watermark extends PdfPageEventHelper {
/**
* 水印字体
*/
private static final Font FONT = new Font(Font.FontFamily.HELVETICA, 20, 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);
}
}
}
}
4.创建单元格工具类
package com.tedu.util;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
/**
* pdf的单元格操作
*
* @author syl
*/
public class PdfCellUtils {
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并、设置单元格内边距)
* @param value 单元格的值
* @param font 字体
* @param align 对齐方式
* @param colspan 合并
* @param borerFlag 是否设置内边距,否则使用默认边距
* @return
*/
public static PdfPCell createCell(String value, Font font, int align, int colspan, boolean borerFlag) {
PdfPCell cell=new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
//横向合并单元格
cell.setColspan(colspan);
//纵向合并
//cell.setRowspan(colspan);
//设置短句
cell.setPhrase(new Phrase(value,font));
//内边距
cell.setPadding(3.0f);
//设置边框宽度,0表示无边框
cell.setBorder(0);
if (borerFlag){
cell.setBorder(0);
cell.setPaddingTop(15.0f);
cell.setPaddingBottom(15.0f);
}
return cell;
}
/**
* 创建单元格指定字体对齐方式
* @param value
* @param font
* @param align
* @return
*/
public static 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;
}
/**
* 创建单元格指定字体,水平,边框宽度:0表示无宽度,内边距
* @param value
* @param font
* @param align
* @param borderWith
* @param paddingSize
* @param flag
* @return
*/
public static PdfPCell createCell(String value, Font font, int align, float [] borderWith, float [] paddingSize,boolean flag) {
PdfPCell cell=new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setPhrase(new Phrase(value,font));
cell.setBorderWidthTop(borderWith[0]);
cell.setBorderWidthBottom(borderWith[1]);
cell.setBorderWidthLeft(borderWith[2]);
cell.setBorderWidthRight(borderWith[3]);
cell.setPaddingTop(paddingSize[0]);
cell.setPaddingBottom(paddingSize[1]);
if (flag){
cell.setColspan(2);
}
return cell;
}
}
5.字体样式工具类
package com.tedu.util;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.BaseFont;
/**
* TODO
*
* @author syl
*/
public class PdfFont {
/**
* 标题字体
*/
public static Font titleFont;
/**
* 表头行字体
*/
public static Font headFont;
/**
* 关键字
*/
public static Font keyFont;
/**
* 文本字体
*/
public static Font textFont;
/**
* 最大宽度
*/
public static int maxWidth=520;
/**
* 初始化字体
*/
static {
try {
//使用iTextAsian.jar中的字体,NOT_EMBEDDED表示不嵌入
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();
}
}
}
6.详细代码
package com.tedu.controller;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.tedu.entity.Student;
import com.tedu.service.StudentService;
import com.tedu.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
/**
* TODO
*
* @author syl
*/
@RestController
@RequestMapping({"pdf1/","pdf"})
@Api(value = "pdf操作",tags = "pdf操作")
public class PdfController {
/**
* 注入service
*/
@Autowired
private StudentService studentService;
/**
* produces = "application/pdf"必不可少,标志请求返回值类中
* @param response
*/
@GetMapping(value = "generate",produces = "application/pdf")
@ApiOperation("生成pdf")
public void generatePdf(HttpServletResponse response){
//创建文档
Document document=new Document(PageSize.A4);
OutputStream out = null;
try {
//获取输出流
out=response.getOutputStream();
//构建writer
PdfWriter writer = PdfWriter.getInstance(document,out);
//设置页眉页脚必须在文档打开之前
writer.setPageEvent(new HeaderFooter());
//打开文档
document.open();
//设置水印
new Watermark("student").onEndPage(writer,document);
//生成pdf内容
generate(document);
//清除首部的空白行
response.reset();
//设置请求头和请求类型
response.setHeader("Content-Disposition", "attachment; filename=student.pdf");
response.setContentType("application/pdf;charset=UTF-8");
//关闭文档
document.close();
out.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
//关闭流对象
if (out!=null){
try {
out.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
}
private void generate(Document document) throws DocumentException {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//初始化列头行
List<String> list=initTableHead();
//设置列宽
float [] widths={20,30,30,20,20,20,20,50,50};
//生成表格
PdfPTable table=new PdfPTable(widths);
table.addCell(PdfCellUtils.createCell("学生成绩表", PdfFont.titleFont, Element.ALIGN_CENTER, list.size(), true));
//生成列头
for (int i=Common.Number.ZERO;i<list.size();i++){
table.addCell(PdfCellUtils.createCell(list.get(i), PdfFont.headFont, Element.ALIGN_CENTER));
}
//调用服务
List<Student> studentList = studentService.findAll(new Student(), 1, 100).getRecords();
//生成表格内容
for (Student student : studentList) {
table.addCell(PdfCellUtils.createCell(student.getSno(),PdfFont.textFont,Element.ALIGN_CENTER));
table.addCell(PdfCellUtils.createCell(student.getClass1(),PdfFont.textFont,Element.ALIGN_CENTER));
table.addCell(PdfCellUtils.createCell(student.getName(),PdfFont.textFont,Element.ALIGN_CENTER));
table.addCell(PdfCellUtils.createCell(student.getSex(),PdfFont.textFont,Element.ALIGN_CENTER));
table.addCell(PdfCellUtils.createCell(student.getChinese(),PdfFont.textFont,Element.ALIGN_CENTER));
table.addCell(PdfCellUtils.createCell(student.getMath(),PdfFont.textFont,Element.ALIGN_CENTER));
table.addCell(PdfCellUtils.createCell(student.getEnglish(),PdfFont.textFont,Element.ALIGN_CENTER));
table.addCell(PdfCellUtils.createCell(sdf.format(student.getCreateTime()),PdfFont.textFont,Element.ALIGN_CENTER));
table.addCell(PdfCellUtils.createCell(sdf.format(student.getUpdateTime()),PdfFont.textFont,Element.ALIGN_CENTER));
}
document.add(table);
}
/**
* 初始化列头行
* @return
*/
private List<String> initTableHead() {
List<String> list=new ArrayList<>();
list.add("学号");
list.add("班级");
list.add("姓名");
list.add("性别");
list.add("语文");
list.add("数学");
list.add("英语");
list.add("创建时间");
list.add("修改时间");
return list;
}
}