记录一次Java接口使用IText生成PDF
场景是需要将后端接口的数据生成为PDF的表格,这里文件的保存先以保存到本地为例
1.本地地址获取
- 本地的地址是获取用户home目录并创建文件夹Documents
示例如下:
String savePath = FileSystemView.getFileSystemView().getHomeDirectory().getPath()+"/Documents/";//存储文件夹
//新建目标文件
File file = new File(savePath);
file.mkdirs();
2.数据组装为表格
- 对pdf 的要求是把数据组成表格
用PdfPTable table = new PdfPTable(12);规定表格有12列,后面调整列的多少来实现不同宽度的单元格
然后代码
示例如下:
public void savePDF(String id,String bsType) {
Document document = new Document();
try {
PdfWriter.getInstance(document, new FileOutputStream(new File("C:\\Users\\Revolt\\Desktop\\cel.pdf")));//保存位置
document.open();
// 加载字体文件
BaseFont baseFont = BaseFont.createFont("C:/Windows/Fonts/SIMSUN.TTC,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
// 创建字体
Font font = new Font(baseFont, 12);
// Add title
Paragraph title = new Paragraph("这是标题", font);
title.setAlignment(Element.ALIGN_CENTER);
document.add(title);
document.add(Chunk.NEWLINE);
// Create table
PdfPTable table = new PdfPTable(12);
table.setWidthPercentage(100);
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
CommonVo commonDetail = BusinessClient.getCommonDetail(id, bsType);
document.add(new Paragraph("承办部门:"+commonDetail.getHandlerDept(), font));
PdfPCell cell = new PdfPCell(new Phrase("名称", font));
cell.setColspan(2);
table.addCell(cell);
cell = new PdfPCell(new Phrase(commonDetail.getName(), font));
cell.setColspan(4);
table.addCell(cell);
cell = new PdfPCell(new Phrase("编号", font));
cell.setColspan(2);
table.addCell(cell);
cell = new PdfPCell(new Phrase(commonDetail.getCode(), font));
cell.setColspan(4);
table.addCell(cell);
}
document.add(table);
document.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
3.问题
- 遇到的问题
主要是字体,itext有内置字体,我这里使用不生效,或是中文不显示,应该是字体编码问题导致的,我这里索性就使用了本地的字体,这个地址是Windows系统字体库地址.
同样需要注意的问题是,如果需要部署到其他系统使用(Linux),要注意对应系统上的字体地址,以及是否有读写使用权限
示例如下:
// 加载字体文件
BaseFont baseFont = BaseFont.createFont("C:/Windows/Fonts/SIMSUN.TTC,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
// 创建字体
Font font = new Font(baseFont, 12);
4.不是本地,需要上传的情况
- 文件需要上传的话,就需要把文件转成输入流,供上传接口使用
示例如下:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
InputStream inputStream = (InputStream) bais;//转为输入流用于上传文件
return inputStream;