传统项目,尤其是办公系统经常会有在线生成word或者是pdf文档的需求。这里介绍一种基于itextpdf的实现方式,这种方式能同时适用于Windows和Linux系统。闲话少叙,实现步骤如下:
一 在pom.xml引入itextpdf
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.2</version>
</dependency>
jar包可以去我的资源里下载(免费)
二 根据需求写后台实现方法
我这个项目的需求是生成类似于表格的pdf文档,代码如下
/**
* 相对方资信调查导出基本信息及审批信息
* @param dataMap 数据map
* @param pdfPath pdf文件路径
* @throws DaoriginException 封装异常
*/
public static void createPDFForCont(Map dataMap,String pdfPath) throws DaoriginException{
// 创建word文档,并设置纸张的大小
com.itextpdf.text.Document document = new com.itextpdf.text.Document(com.itextpdf.text.PageSize.A4);
document.setMargins(0, 0, 12, 12);
try {
com.itextpdf.text.pdf.PdfWriter.getInstance(document,new FileOutputStream(pdfPath));
document.open();
//设置字体 宋体四号
com.itextpdf.text.Font font01 = ChineseFont7();
//添加标题
com.itextpdf.text.Paragraph ptile1 =new com.itextpdf.text.Paragraph("\r\n相对方调查审批单\r\n ",font01);
ptile1.setAlignment(Paragraph.ALIGN_CENTER);
document.add(ptile1);
//设计表格 A4大小,四列,对应列宽分别别为 110,150,90,150
PdfPTable table = new PdfPTable(4);
table.setWidthPercentage(new float[]{110,150,90,150},com.itextpdf.text.PageSize.A4);
table.setSplitLate(false); //跨页显示
//填充基本信息
ContractRelativeCreditVO vo = (ContractRelativeCreditVO) dataMap.get("creditVO");
table = addPDFCell(table, "对方单位名称", DataCheck.isNull(vo.getRelativeName())?"-":vo.getRelativeName(), 0, 0);
table = addPDFCell(table, "地址", DataCheck.isNull(vo.getRelativeAddress())?"-":vo.getRelativeAddress(), 0, 0);
table = addPDFCell(table, "委托代理人", DataCheck.isNull(vo.getProxyMan())?"-":vo.getProxyMan(), 0, 0);
table = addPDFCell(table, "联系方式", DataCheck.isNull(vo.getLinkTel())?"-":vo.getLinkTel(), 0, 0);
table = addPDFCell(table, "类型", DataCheck.isNull(vo.getType())?"-":vo.getType(), 0, 0);
table = addPDFCell(table, "招标项目/拟采购物资", DataCheck.isNull(vo.getBidding())?"-":vo.getBidding(), 0, 0);
table = addPDFCell(table, "预算金额(万元)", DataCheck.isNull(vo.getAmount())?"-":vo.getAmount(), 0, 0);
table = addPDFCell(table, "拟开展业务简介", DataCheck.isNull(vo.getIntroduction())?"-":vo.getIntroduction(), 0, 0);
table = addPDFCell(table, "资质要求", DataCheck.isNull(vo.getQualification())?"-":vo.getQualification(), 70, 3);
table = addPDFCell(table, "资质明细", DataCheck.isNull(vo.getDetailsName())?"-":vo.getDetailsName(), 70, 3);
table = addPDFCell(table, "其他说明", DataCheck.isNull(vo.getOther())?"-":vo.getOther(), 0, 0);
table = addPDFCell(table, "经办人", DataCheck.isNull(vo.getHandleUser())?"-":vo.getHandleUser(), 0, 0);
table = addPDFCell(table, "经办人电话", DataCheck.isNull(vo.getHandleTel())?"-":vo.getHandleTel(), 0, 0);
table = addPDFCell(table, "经办部门", DataCheck.isNull(vo.getHandleOrg())?"-":vo.getHandleOrg(), 0, 0);
Date createDate = new Date(vo.getCreatedAt());
vo.setCreateDateStr(CommonUtil.formatDateToString(createDate, ""));
table = addPDFCell(table, "经办日期", DataCheck.isNull(vo.getCreateDateStr())?"-":vo.getCreateDateStr(), 0, 3);
document.add(table);
//填充审批意见表标题,页面排版,这里加了一行和上边的基本信息做区分
PdfPTable table2h = new PdfPTable(1);
table2h.setWidthPercentage(new float[]{500},com.itextpdf.text.PageSize.A4);
table2h.setSplitLate(false);
table2h = addPDFCell2(table2h, "审批意见");
document.add(table2h);
//设计审批意见表
PdfPTable table2 = new PdfPTable(4);
table2.setWidthPercentage(new float[]{110,150,90,150},com.itextpdf.text.PageSize.A4);
table2.setSplitLate(false);
//标题
table2 = addPDFCell2(table2, "处理人");
table2 = addPDFCell2(table2, "意见");
table2 = addPDFCell2(table2, "处理节点");
table2 = addPDFCell2(table2, "处理完毕时间");
//动态添加内容
List<ProcessOpinionVO> list = (List<ProcessOpinionVO>) dataMap.get("opinionList");
for (ProcessOpinionVO processOpinionVO : list) {
table2 = addPDFCell2(table2, DataCheck.isNull(processOpinionVO.getHandleUser())?"-":processOpinionVO.getHandleUser());
table2 = addPDFCell2(table2, DataCheck.isNull(processOpinionVO.getOpinionDesc())?"-":processOpinionVO.getOpinionDesc());
table2 = addPDFCell2(table2, DataCheck.isNull(processOpinionVO.getActTaskName())?"-":processOpinionVO.getActTaskName());
table2 = addPDFCell2(table2, DataCheck.isNull(processOpinionVO.getEndTime())?"-":processOpinionVO.getEndTime());
}
document.add(table2);
document.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (com.itextpdf.text.DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 设置宋体四号字体
*/
public static com.itextpdf.text.Font ChineseFont7()
{
com.itextpdf.text.pdf.BaseFont baseFont=null;
try {
//字体文件存放路径,对应字体文件可以去我的资源下载(免费)
String FontsUrl = LawConfig.officeHtml+"/font/";
//宋体四号
baseFont = com.itextpdf.text.pdf.BaseFont.createFont(FontsUrl+"songti.ttf", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
// baseFont=BaseFont.createFont("STSong-Light","UniGB-UCS2-H", true);
} catch (com.itextpdf.text.DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}//,8,Font.NORMAL,Color.BLACK
com.itextpdf.text.Font chineseFont=new com.itextpdf.text.Font(baseFont);
chineseFont.setSize(14f);
chineseFont.setStyle(com.itextpdf.text.Font.NORMAL);
chineseFont.setColor(BaseColor.BLACK); //BaseColor.GRAY
return chineseFont;
}
public static com.itextpdf.text.Font ChineseFont8()
{
com.itextpdf.text.pdf.BaseFont baseFont=null;
try {
String FontsUrl = LawConfig.officeHtml+"/font/";
//宋体小四号
baseFont = com.itextpdf.text.pdf.BaseFont.createFont(FontsUrl+"songti.ttf", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
// baseFont=BaseFont.createFont("STSong-Light","UniGB-UCS2-H", true);
} catch (com.itextpdf.text.DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}//,8,Font.NORMAL,Color.BLACK
com.itextpdf.text.Font chineseFont=new com.itextpdf.text.Font(baseFont);
chineseFont.setSize(12f);
chineseFont.setStyle(com.itextpdf.text.Font.NORMAL);
chineseFont.setColor(BaseColor.BLACK); //BaseColor.GRAY
return chineseFont;
}
/**
* 表中添加行数据公共方法
* @param table 表格
* @param cellName 行标题
* @return
*/
public static PdfPTable addPDFCell2(PdfPTable table ,String cellName) {
//宋体小四号
com.itextpdf.text.Font font02 = ChineseFont8();
PdfPCell cell = new PdfPCell(new Paragraph(cellName,font02));
cell.setBorderColor(BaseColor.BLACK);
cell.setPaddingLeft(10);
cell.setHorizontalAlignment(Paragraph.ALIGN_CENTER);
cell.setVerticalAlignment(Paragraph.ALIGN_MIDDLE);
table.addCell(cell);
return table;
}
到这里在对应的pdf路径下就已经生成了pdf文件
打开pdf文档可以看见实现效果
个人学习的话到这一步就可以了,但是真实的项目中,不可能让客户直接去访问服务器上指定路径下的文件,这里采用流的方式将文件回写到前端
三 文件回显(下载)
try {
//获取文件输入流 指向pdf的绝对路径
FileInputStream fis = new FileInputStream(LawConfig.officeHtml+busiId+".pdf");
// 设置文件名
String filename = "审批单.pdf";
Boolean flag = request.getHeader("User-Agent").indexOf("like Gecko") > 0;
if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") > 0 || flag) {
filename = URLEncoder.encode(filename, "UTF-8");// IE浏览器
} else {
// 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,
// 这个文件名称用于浏览器的下载框中自动显示的文件名
filename = new String(filename.replaceAll(" ", "").getBytes("UTF-8"), "ISO8859-1");
}
filename = filename.replaceAll("\\+", "%20");
//设置响应类型
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "attachment;fileName=" + filename);// 设置文件名
byte[] buffer = new byte[1024];
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
}
这样一个完整的pdf制作回显就完成了。