使用 iText 导出 pdf 表格
iText 是一种生成 PDF 报表的 Java 组件,先把 jar 包下下来,maven 依赖如下:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.0.6</version>
</dependency>
1. Hello World
接下来咱们就来搞一个 PDF 入门案例吧。
新建一个 SpringBoot 项目: 导入 POM 依赖
Controller:
@RestController
@RequestMapping("/pdf")
public class PdfContoller {
@Autowired
private PdfService pdfService;
@PostMapping("/exportPdf")
public void exportPdf() {
pdfService.exportPdf();
}
}
Service:
public interface PdfService {
void exportPdf();
}
ServiceImpl:
@Service
@Slf4j
public class PdfServiceImpl implements PdfService {
@Override
public void exportPdf() {
log.info("进入到方法exportPdf()");
String fileName = "test.pdf";
try {
PdfUtil.createPdf(fileName);
} catch (DocumentException e) {
log.error("【DocumentException】报错信息为{}", e.getMessage());
} catch (FileNotFoundException e) {
log.error("【FileNotFoundException】报错信息为{}", e.getMessage());
}
log.info("生成pdf文件完毕");
}
}
util:
public class PdfUtil {
public static void createPdf(String fileName) throws DocumentException, FileNotFoundException {
Document document = new Document(PageSize.A4);
PdfWriter.getInstance(document, new FileOutputStream(fileName));
document.open();
document.add(new Paragraph("Hello World"));
document.close();
}
}
调用接口:
http://localhost:8080/pdf/exportPdf
会在当前工程下面生成一个 test.pdf 文件: 好了,iText 入门就到这了。
2. 生成一个表格的 PDF 文件
在工作中,用到比较多的就是导出 PDF 表格了,这里要用到一个很关键的类com.itextpdf.text.pdf.PDFPTable 。
生成一个如下的表格:
这是一个 2 列 5 行的表格。其中,单元格 five 占据 2 列;单元格 six 占据 两行。好了,接下来看看如何实现吧。
PdfServiceImpl:
@Override
public void exportPdf2() {
String fileName = "test2.pdf";
try {
PdfUtil.createPdf2(fileName);
} catch (DocumentException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
PdfUtil:
package com.zzc.hardcore.util;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class PdfUtil {
public static String fontPath = "C:/Users/zzc/Desktop/msyh.ttc,0";
public static BaseFont baseFont = null;
static {
try {
baseFont = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void createPdf2(String fileName) throws DocumentException, FileNotFoundException {
Document document = new Document(PageSize.A4);
PdfWriter instance = PdfWriter.getInstance(document, new FileOutputStream(fileName));
document.open();
Paragraph title = new Paragraph("Hello World");
Font font = new Font(baseFont, 8);
title.setFont(font);
title.setAlignment(Element.ALIGN_CENTER);
document.add(title);
PdfPTable table = createTable();
document.add(table);
document.close();
}
public static PdfPTable createTable() throws DocumentException{
PdfPTable table = doCreateTable();
PdfPCell cell11 = createSpecialCell("one");
table.addCell(cell11);
PdfPCell cell12 = createCell("two");
cell12.setBorder(0);
table.addCell(cell12);
PdfPCell cell21 = createCell("three");
cell21.setHorizontalAlignment(Element.ALIGN_CENTER);
cell21.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(cell21);
PdfPCell cell22 = createCell("four");
table.addCell(cell22);
PdfPCell cell3 = createCell("five");
cell3.setColspan(2);
table.addCell(cell3);
PdfPCell cell41 = createCell("six");
cell41.setMinimumHeight(2 * 20);
cell41.setRowspan(2);
table.addCell(cell41);
PdfPCell cell42 = createCell("seven");
table.addCell(cell42);
PdfPCell cell43 = createCell("eight");
table.addCell(cell43);
return table;
}
public static PdfPTable doCreateTable() throws DocumentException {
int columns = 2;
PdfPTable table = new PdfPTable(columns);
table.setWidthPercentage(100);
table.setSpacingBefore(20f);
table.setSpacingAfter(20f);
float[] columnWidths = {2f, 5f};
table.setWidths(columnWidths);
return table;
}
public static PdfPCell createCell(String cellContent) {
Phrase phrase = new Phrase(cellContent);
phrase.setFont(new Font(baseFont, 5));
PdfPCell cell = new PdfPCell(phrase);
return cell;
}
public static PdfPCell createSpecialCell(String cellContent) {
PdfPCell cell = createCell(cellContent);
cell.setBorderColor(BaseColor.BLUE);
cell.setPaddingLeft(10);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
return cell;
}
}
说明:
- 要想显示中文字体,必须引入字体文件,我这里免费提供一个 pdf字体下载
- PDF 中的 API 使用:Document、PdfPTable、PdfPCell
Document
Document document = new Document(PageSize.A4);
PdfWriter instance = PdfWriter.getInstance(document, new FileOutputStream(fileName));
document.open();
document.close();
pdf 文件中需要什么内容,直接调用 document.add() 进行添加
PdfPTable
table.setWidthPercentage(100);
table.setSpacingBefore(20f);
table.setSpacingAfter(20f);
table.setWidths(columnWidths);
表格中添加单元格,必须得调用:table.addCell();
PdfPCell
cell.setBorderColor(BaseColor.BLUE);
cell12.setBorder(0);
cell.setPaddingLeft(10);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setMinimumHeight();
cell.setColspan(2);
cell.setRowspan(2);
【注意】:每一行的长度要和初始化表格的长度相等,即要把整行给占满,否则后面的都不会打印出来
如上图,大致意思是:如果你是一个 5 * 2 的单元格,并且,每一个单元格默认宽度为 1,那么,每一行的单元格必须要有 2 个,这样,才会默认切换到下一行去。
3. 下载生成的 PDF 文件
前面的东西都是放到 java 项目中去跑的,没有太多实际用处,在 web 项目中用到才算真正的应用。接下来咱们就通过浏览器去下载生成的 pdf 文件。
咱们下载前面生成的 pdf 文件:
PdfContoller:
@PostMapping("/exportPdf2")
public void exportPdf2(HttpServletResponse response) {
pdfService.exportPdf2(response);
}
PdfServiceImpl:
@Override
public void exportPdf2(HttpServletResponse response) {
String fileName = "test2.pdf";
try {
PdfUtil.createPdf2(fileName);
downLoadFile(fileName, response);
deleteFile(new File(fileName));
} catch (DocumentException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
下载 pdf 文件:
public boolean downLoadFile(String fileName, HttpServletResponse response) {
boolean flag = false;
log.info("【下载文件】文件名为:{}", fileName);
File file = new File(fileName);
if (!file.exists()) {
log.error("【下载文件】文件{}不存在", fileName);
return flag;
}
try {
InputStream in = new FileInputStream(fileName);
OutputStream outputStream = response.getOutputStream();
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.addHeader("Content-Length", "" + file.length());
response.setContentType("application/pdf");
IOUtils.copy(in, outputStream);
flag = true;
in.close();
outputStream.close();
} catch (Exception e) {
log.error("【下载文件】下载文件失败,失败信息为{}", e.getMessage());
return flag;
}
return flag;
}
删除临时生成的pdf文件:
public static boolean deleteFile(File file) {
if (!file.exists()) {
return false;
}
if (file.isDirectory()) {
String[] children = file.list();
for (int i=0; i<children.length; i++) {
boolean success = deleteFile(new File(file, children[i]));
if (!success) {
return false;
}
}
}
return file.delete();
}
|