一、相关依赖
<!-- itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
二、字体库
字体存放的跟路径,win默认为'C:\Windows\Fonts\',缺少的字体可以从这里拷贝,或者其他特殊字体
直接指定本地很麻烦,如果部署到服务器服务器也要下载相关字体还要修改配置,放到项目本地比较方便,我拷贝了黑体和宋体,存放在项目fonts目录
需要配置构建
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>fonts/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>fonts/*</include>
</includes>
</resource>
</resources>
</build>
三、编写工具类
@Slf4j
@Component
public class PdfUtils {
/**
* 字体存放的跟路径,win默认为'C:\Windows\Fonts\',缺少的字体可以从这里拷贝,或者其他特殊字体
*/
private static final String FONT_PATH = "/fonts/";
/**
* 默认黑体
*/
private static final String FONT_NAME = "simhei.ttf";
/**
* 标题默认样式
*/
public static Font titleFont = PdfUtils.setFont(FONT_NAME, 14, Font.BOLD, BaseColor.BLACK);
public static Font headFont = PdfUtils.setFont(FONT_NAME, 12, Font.BOLD, BaseColor.BLACK);
public static Font headBody = PdfUtils.setFont(FONT_NAME, 12, Font.NORMAL, BaseColor.BLACK);
public static Font keyFont = PdfUtils.setFont(FONT_NAME, 10, Font.BOLD, BaseColor.BLACK);
public static Font textFont = PdfUtils.setFont(FONT_NAME, 10, Font.NORMAL, BaseColor.BLACK);
/**
* 纸张大小
*/
private static final Rectangle RECTANGLE = PageSize.A4;
/**
* 设置字体默认值
*
* @return
* @throws DocumentException
* @throws IOException
*/
private static BaseFont createBaseFont(String fontName) throws DocumentException, IOException {
// 默认为宋体
if (fontName == null) {
fontName = FONT_NAME;
}
String fontPre = fontName.substring(fontName.lastIndexOf(".") + 1);
if ("ttc".equals(fontPre)) {
// ttc格式的字体需要加上后缀
fontName = fontName + ",0";
}
String font = FONT_PATH + fontName;
return BaseFont.createFont(font, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
}
/**
* 设置字体
*
* @return
*/
public static Font setFont() {
return setFont(null, null, null, null);
}
public static Font setFont(Integer fontSize) {
return setFont(null, fontSize, null, null);
}
public static Font setFont(Integer fontSize, BaseColor fontColor) {
return setFont(null, fontSize, null, fontColor);
}
/**
* @param fontName 字体名称 默认宋体
* @param fontSize 字体大小 默认12号
* @param fontStyle 字体样式
* @param fontColor 字体颜色 默认黑色
* @return
*/
public static Font setFont(String fontName, Integer fontSize, Integer fontStyle, BaseColor fontColor) {
try {
BaseFont baseFont = createBaseFont(fontName);
Font font = new Font(baseFont);
if (fontSize != null) {
font.setSize(fontSize);
}
if (fontStyle != null) {
font.setStyle(fontStyle);
}
if (fontColor != null) {
font.setColor(fontColor);
}
return font;
} catch (Exception e) {
log.error("设置字体失败", e);
return null;
}
}
/**
* 创建pdf文档
*
* @param rectangle 纸张大小
* @return pdf文档
*/
public static Document createDocument(Rectangle rectangle) {
if (rectangle == null) {
rectangle = RECTANGLE;
}
return new Document(rectangle, 50, 50, 80, 50);
}
/**
* 绘制标题
*
* @param font 样式
* @param titleName 标题名
* @return 标题段落
*/
public static Paragraph setParagraph(Font font, String titleName) {
Paragraph paragraph = new Paragraph(titleName, font);
//设置文字居中
paragraph.setAlignment(Element.ALIGN_CENTER);
//行间距
paragraph.setLeading(5f);
//设置段落上空白
paragraph.setSpacingBefore(-20f);
//设置段落下空白
paragraph.setSpacingAfter(15f);
return paragraph;
}
/**
* 创建表格
*
* @param widths 表头
* @return PdfPTable
*/
private static PdfPTable createTable(float[] widths) {
PdfPTable table = new PdfPTable(widths);
try {
// 设置表格大小
table.setTotalWidth(RECTANGLE.getWidth() - 100);
table.setLockedWidth(true);
// 居中
table.setHorizontalAlignment(Element.ALIGN_CENTER);
// 边框
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
public static PdfPCell createCell(Image image, Font font, int align, int colspan, int rowspan) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setRowspan(rowspan);
cell.setFixedHeight(rowspan * 25f);
cell.setImage(image);
// cell.setPhrase(new Phrase(new Chunk(image, 0, 0,false)));
return cell;
}
public static PdfPCell createCell(Image image, Font font, int align, int colspan, int rowspan, int borderWidthTop, int borderWidthRight, int borderWidthBottom, int borderWidthLeft) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setRowspan(rowspan);
cell.setFixedHeight(rowspan * 25f);
cell.setImage(image);
//去除边框
cell.setBorderWidthTop(borderWidthTop);
cell.setBorderWidthRight(borderWidthRight);
cell.setBorderWidthBottom(borderWidthBottom);
cell.setBorderWidthLeft(borderWidthLeft);
return cell;
}
/**
* 创建单元格(指定字体)
*
* @param value
* @param font
* @return
*/
public static 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));
cell.setFixedHeight(25f);
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));
cell.setFixedHeight(25f);
return cell;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并)
*
* @param value
* @param font
* @param align
* @param colspan
* @return
*/
public static 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;
}
public static PdfPCell createCell(String value, Font font, int align, int colspan, int rowspan) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setRowspan(rowspan);
cell.setFixedHeight(rowspan * 25f);
cell.setPhrase(new Phrase(value, font));
return cell;
}
public static PdfPCell createCell(String value, Font font, int align, int colspan, int rowspan, int borderWidthTop, int borderWidthRight, int borderWidthBottom, int borderWidthLeft) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setRowspan(rowspan);
cell.setFixedHeight(rowspan * 25f);
cell.setPhrase(new Phrase(value, font));
//去除边框
cell.setBorderWidthTop(borderWidthTop);
cell.setBorderWidthRight(borderWidthRight);
cell.setBorderWidthBottom(borderWidthBottom);
cell.setBorderWidthLeft(borderWidthLeft);
return cell;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并、设置单元格内边距)
*
* @param value
* @param font
* @param align
* @param colspan
* @param boderFlag
* @return
*/
public static 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 static 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.setFixedHeight(25f);
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;
}
四、编写案例
单个pdf和多个pdf压缩zip案例
@GetMapping("/pdf")
public void downloadPDF(HttpServletResponse response) {
try (BufferedOutputStream os = new BufferedOutputStream(response.getOutputStream())) {
// 1.设置输出的文件名称
String fileName = "考勤报表.pdf";
response.reset();
response.setHeader("Content-Type", "application/pdf-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
// 2.创建pdf文档,并且设置纸张大小为A4
Document document = PdfUtils.createDocument(response, fileName);
PdfWriter.getInstance(document, os);
// 3.打开文档
document.open();
// 4.设置标题
String titleName = "这 个 是 标 题";
// 设置字体样式:黑体 20号 加粗 红色
Font titleFont = PdfUtils.setFont("simhei.ttf", 20, Font.BOLD, BaseColor.RED);
Paragraph paragraph = PdfUtils.setParagraph(titleFont, titleName);
// 5.设置表格
// 定义列名
String[] title = {"邮箱", "姓名", "密码", "状态"};
// 获取列表数据
// 设置表头字体样式:黑体 14号 加粗 黑色
// 设置正文字体样式:12号
Font headFont = PdfUtils.setFont("simhei.ttf", 12, Font.BOLD, BaseColor.BLACK);
Font textFont = PdfUtils.setFont(12);
// 模拟获取数据
List<UserVO> dataList = getData();
PdfPTable table = PdfUtils.setTable(headFont, textFont, title, dataList);
// 8.填充内容
document.add(paragraph);
document.add(table);
// 关闭资源
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@GetMapping("/pdf1")
public void downloadPDF1(HttpServletResponse response) {
try {
ZipOutputStream os = new ZipOutputStream (response.getOutputStream());
response.setContentType("application/octet-stream");
// 1.设置输出的文件名称
String fileName = "考勤报表.zip";
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
for (int i = 0; i < 3; i++) {
// 2.创建pdf文档,并且设置纸张大小为A4
Document document = PdfUtils.createDocument(response, fileName);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
// 3.打开文档
document.open();
// 4.设置标题
String titleName = "这 个 是 标 题";
// 设置字体样式:黑体 20号 加粗 红色
Font titleFont = PdfUtils.setFont("simhei.ttf", 20, Font.BOLD, BaseColor.RED);
Paragraph paragraph = PdfUtils.setParagraph(titleFont, titleName);
// 5.设置表格
// 定义列名
String[] title = {"邮箱", "姓名", "密码", "状态"};
// 获取列表数据
// 设置表头字体样式:黑体 14号 加粗 黑色
// 设置正文字体样式:12号
Font headFont = PdfUtils.setFont("simhei.ttf", 12, Font.BOLD, BaseColor.BLACK);
Font textFont = PdfUtils.setFont(12);
// 模拟获取数据
List<UserVO> dataList = getData();
PdfPTable table = PdfUtils.setTable(headFont, textFont, title, dataList);
// 8.填充内容
document.add(paragraph);
document.add(table);
// 关闭资源
document.close();
byte[] xmpMetadata = baos.toByteArray();
os.putNextEntry(new ZipEntry("test"+i+".pdf"));
os.write(xmpMetadata);
os.flush();
}
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private List<UserVO> getData() {
List list = new ArrayList<UserVO>();
for (int i = 0; i < 100; i++) {
UserVO user = new UserVO();
user.setEmail("名称-" + i);
user.setUserName("地址-" + i);
user.setPassword("20"+i);
user.setState(true);
list.add(user);
}
return list;
}
相关参考: