导出效果如下
代码
1、常用的几个方法放到了一个工具类中
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
/**
* @Description: pdf工具类
* @author: kylin
* @create: 2018-01-10 16:22
**/
public class PDFUtil {
/**
* 获取指定内容与字体的单元格
* @param string
* @param font
* @return
*/
public static PdfPCell getPDFCell(String string, Font font)
{
//创建单元格对象,将内容与字体放入段落中作为单元格内容
PdfPCell cell=new PdfPCell(new Paragraph(string,font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
//设置最小单元格高度
cell.setMinimumHeight(25);
return cell;
}
/**
* 合并行的静态函数
* @param str
* @param font
* @param i
* @return
*/
public static PdfPCell mergeRow(String str,Font font,int i) {
//创建单元格对象,将内容及字体传入
PdfPCell cell=new PdfPCell(new Paragraph(str,font));
//设置单元格内容居中
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
//将该单元格所在列包括该单元格在内的i行单元格合并为一个单元格
cell.setRowspan(i);
return cell;
}
/**
* 合并列的静态函数
* @param str
* @param font
* @param i
* @return
*/
public static PdfPCell mergeCol(String str,Font font,int i) {
PdfPCell cell=new PdfPCell(new Paragraph(str,font));
cell.setMinimumHeight(25);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
//将该单元格所在行包括该单元格在内的i列单元格合并为一个单元格
cell.setColspan(i);
return cell;
}
}
2、为每一页都加上背景图
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.IOException;
/**
* @Description: 为每一页pdf都生成背景图片
* @author: kylin
* @create: 2018-01-08 18:00
**/
public class BackGroundImage extends PdfPageEventHelper {
private String picPath = "";
public String getPicPath() {
return picPath;
}
public void setPicPath(String picPath) {
this.picPath = picPath;
}
public BackGroundImage(){
}
public BackGroundImage(String path){
this.picPath = path;
}
@Override
public void onStartPage(PdfWriter pdfWriter, Document document) {
try {
Image image = Image.getInstance(picPath);
image.setAlignment(image.UNDERLYING);
image.setAbsolutePosition(0,0);
image.scaleAbsolute(595,842);
document.add(image);
} catch (BadElementException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
super.onStartPage(pdfWriter, document);
}
}
3、生成pdf(图片那块由于我是从数据库取出的byte[],所以处理的有点繁琐,可以按自己的方式简化)
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.kunbo.modules.station.entity.SysPassRecordEntity;
import org.apache.commons.codec.binary.Base64;
/**
* 创建pdf
* @Author kylin
* 2018.1.8
*/
public class GeneratePDF {
/**
* 生成绿通车辆数据pdf
* @param os
* @param prList
*/
public static void createPDF1(OutputStream os, List<SysPassRecordEntity> prList) {
// 新建document对象
Document document = new Document(PageSize.A4,36,36,126,36);
try {
//添加中文字体
BaseFont bfChinese=BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
//设置字体样式
Font textFont = new Font(bfChinese,12,Font.NORMAL);//正常
Font boldFont = new Font(bfChinese,11,Font.BOLD); //加粗
Font firsetTitleFont = new Font(bfChinese,22,Font.BOLD); //一级标题
Font secondTitleFont = new Font(bfChinese,15,Font.BOLD); //二级标题
Font underlineFont = new Font(bfChinese,11,Font.UNDERLINE); //下划线斜体
//创建输出流
PdfWriter pdfWriter = PdfWriter.getInstance(document, os);
pdfWriter.setPageEvent(new BackGroundImage("classPath:static/images/bgImg.jpg"));
document.open();
for (int i = 0; i <prList.size() ; i++) {
Paragraph p0 = new Paragraph(" ",textFont);
p0.setLeading(60);
String str = "时间:" + prList.get(i).getRecordDate().substring(0,16)+ " 查验人(签字):" + prList.get(i).getAuUsername()+ " " + prList.get(i).getChannelNum()+ "车道";
Paragraph ph1 = new Paragraph(str,textFont);
ph1.setAlignment(Element.ALIGN_CENTER);
p0.add(ph1);
Paragraph ph2 = new Paragraph(" ",textFont);
p0.add(ph2);
PdfPTable imgTable = new PdfPTable(4);
imgTable.setSpacingBefore(10);
imgTable.setHorizontalAlignment(Element.ALIGN_CENTER);
imgTable.setTotalWidth(new float[]{ 124, 124, 124, 124 }); //设置列宽
imgTable.setLockedWidth(true); //锁定列宽
imgTable.setSpacingAfter(30);
//取出二进制并转为base64字符串
String base64Str1 = Base64.encodeBase64String(prList.get(i).getPhoto1());
String base64Str2 = Base64.encodeBase64String(prList.get(i).getPhoto2());
String base64Str3 = Base64.encodeBase64String(prList.get(i).getPhoto3());
String base64Str4 = Base64.encodeBase64String(prList.get(i).getPhoto4());
//base64解密
String base64Img1 = Base64Helper.getFromBase64(base64Str1);
String base64Img2 = Base64Helper.getFromBase64(base64Str2);
String base64Img3 = Base64Helper.getFromBase64(base64Str3);
String base64Img4 = Base64Helper.getFromBase64(base64Str4);
//字符串处理 利用正则表达式找到首次出现“,”的索引
Matcher matcher1= Pattern.compile(",").matcher(base64Img1);
Matcher matcher2= Pattern.compile(",").matcher(base64Img2);
Matcher matcher3= Pattern.compile(",").matcher(base64Img3);
Matcher matcher4= Pattern.compile(",").matcher(base64Img4);
//转为二进制
byte[] bImg1 = null;
byte[] bImg2 = null;
byte[] bImg3 = null;
byte[] bImg4 = null;
if(matcher1.find()){
bImg1 = Base64.decodeBase64(base64Img1.substring(matcher1.start()+1));
}
if(matcher2.find()){
bImg2 = Base64.decodeBase64(base64Img2.substring(matcher2.start()+1));
}
if(matcher3.find()){
bImg3 = Base64.decodeBase64(base64Img3.substring(matcher3.start()+1));
}
if(matcher4.find()){
bImg4 = Base64.decodeBase64(base64Img4.substring(matcher4.start()+1));
}
Image img1 = Image.getInstance(bImg1);
Image img2 = Image.getInstance(bImg2);
Image img3 = Image.getInstance(bImg3);
Image img4 = Image.getInstance(bImg4);
img1.scaleToFit(120,220);
img2.scaleToFit(120,220);
img3.scaleToFit(120,220);
img4.scaleToFit(120,220);
//填充到table
PdfPCell pdfPCell1 = new PdfPCell(img1);
// pdfPCell1.setFixedHeight(180);
pdfPCell1.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfPCell1.setBorder(PdfPCell.NO_BORDER);
PdfPCell pdfPCell2 = new PdfPCell(img2);
// pdfPCell2.setFixedHeight(180);
pdfPCell2.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfPCell2.setBorder(PdfPCell.NO_BORDER);
PdfPCell pdfPCell3 = new PdfPCell(img3);
// pdfPCell3.setFixedHeight(180);
pdfPCell3.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfPCell3.setBorder(PdfPCell.NO_BORDER);
PdfPCell pdfPCell4 = new PdfPCell(img4);
// pdfPCell4.setFixedHeight(180);
pdfPCell4.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfPCell4.setBorder(PdfPCell.NO_BORDER);
PdfPCell titleCell1 = new PdfPCell(new Paragraph(prList.get(i).getVehicleNum(),textFont));
PdfPCell titleCell2 = new PdfPCell(new Paragraph(prList.get(i).getAxleCount()+"轴",textFont));
PdfPCell titleCell3 = new PdfPCell(new Paragraph(prList.get(i).getGoodsType(),textFont));
PdfPCell titleCell4 = new PdfPCell(new Paragraph(prList.get(i).getWeight()+"吨",textFont));
titleCell1.setHorizontalAlignment(Element.ALIGN_CENTER);
titleCell2.setHorizontalAlignment(Element.ALIGN_CENTER);
titleCell3.setHorizontalAlignment(Element.ALIGN_CENTER);
titleCell4.setHorizontalAlignment(Element.ALIGN_CENTER);
titleCell1.setBorder(PdfPCell.NO_BORDER);
titleCell2.setBorder(PdfPCell.NO_BORDER);
titleCell3.setBorder(PdfPCell.NO_BORDER);
titleCell4.setBorder(PdfPCell.NO_BORDER);
imgTable.addCell(pdfPCell1);
imgTable.addCell(pdfPCell2);
imgTable.addCell(pdfPCell3);
imgTable.addCell(pdfPCell4);
imgTable.addCell(titleCell1);
imgTable.addCell(titleCell2);
imgTable.addCell(titleCell3);
imgTable.addCell(titleCell4);
p0.add(imgTable);
document.add(p0);
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 关闭文档
document.close();
}
/**
* 生成非绿通车辆数据pdf
* @param os
* @param prList
*/
public static void createPDF0(OutputStream os,List<SysPassRecordEntity> prList){
Document document = new Document(PageSize.A4,36,36,126,36);
try {
BaseFont bfChinese=BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
//设置字体样式
Font textFont = new Font(bfChinese,12,Font.NORMAL);//正常
Font boldFont = new Font(bfChinese,11,Font.BOLD); //加粗
Font firsetTitleFont = new Font(bfChinese,22,Font.BOLD); //一级标题
Font secondTitleFont = new Font(bfChinese,15,Font.BOLD); //二级标题
Font underlineFont = new Font(bfChinese,11,Font.UNDERLINE); //下划线斜体
//创建输出流
PdfWriter pdfWriter = PdfWriter.getInstance(document, os);
pdfWriter.setPageEvent(new BackGroundImage("classPath:static/images/bgImg0.jpg"));
document.open();
for (int i = 0; i <prList.size() ; i++) {
Paragraph p0 = new Paragraph();
Paragraph p1 = new Paragraph("收费站名称:" + prList.get(i).getExitStation(),textFont);
p1.setLeading(40);
p0.add(p1);
//创建table对象
PdfPTable table = new PdfPTable(7);
table.setSpacingBefore(10);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.setTotalWidth(new float[]{ 30,80, 80, 80, 80, 80 ,100 }); //设置列宽
table.setLockedWidth(true); //锁定列宽
PdfPCell cell = new PdfPCell();
//添加表格内容
table.addCell(PDFUtil.mergeCol("时间",textFont,2));
table.addCell(PDFUtil.mergeCol(prList.get(i).getRecordDate().substring(0,16), textFont, 3));
table.addCell(PDFUtil.getPDFCell("查验人",textFont));
table.addCell(PDFUtil.getPDFCell(prList.get(i).getAuUsername(), textFont));
table.addCell(PDFUtil.mergeCol("车牌号",textFont,2));
table.addCell(PDFUtil.getPDFCell(prList.get(i).getVehicleNum(), textFont));
table.addCell(PDFUtil.getPDFCell("入口站名",textFont));
table.addCell(PDFUtil.getPDFCell(prList.get(i).getEntrStation(), textFont));
table.addCell(PDFUtil.getPDFCell("记录人",textFont));
table.addCell(PDFUtil.getPDFCell(prList.get(i).getCreator(), textFont));
table.addCell(PDFUtil.mergeRow("出口通行信息", textFont, 2));
table.addCell(PDFUtil.getPDFCell("车道",textFont));
table.addCell(PDFUtil.mergeCol("出口" + prList.get(i).getChannelNum() + "车道", textFont, 3));
table.addCell(PDFUtil.getPDFCell("收费员工号",textFont));
table.addCell(PDFUtil.getPDFCell(prList.get(i).getToUsername(), textFont));
table.addCell(PDFUtil.getPDFCell("车型",textFont));
table.addCell(PDFUtil.mergeCol(String.valueOf(prList.get(i).getAxleCount())+"轴", textFont,3));
table.addCell(PDFUtil.getPDFCell("追缴金额",textFont));
table.addCell(PDFUtil.getPDFCell(String.valueOf(prList.get(i).getAmount()) + "¥", textFont));
cell = PDFUtil.mergeCol("查验情况: 假冒原因:" + prList.get(i).getSpurTypeName(),textFont,7);
cell.setFixedHeight(280);
cell.setVerticalAlignment(Element.ALIGN_TOP);
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
cell.setPaddingTop(10);
cell.setPaddingLeft(10);
table.addCell(cell);
//取出二进制并转为base64字符串
String base64Str1 = Base64.encodeBase64String(prList.get(i).getPhoto1());
String base64Str2 = Base64.encodeBase64String(prList.get(i).getPhoto2());
String base64Str3 = Base64.encodeBase64String(prList.get(i).getPhoto3());
String base64Str4 = Base64.encodeBase64String(prList.get(i).getPhoto4());
//base64解密
String base64Img1 = Base64Helper.getFromBase64(base64Str1);
String base64Img2 = Base64Helper.getFromBase64(base64Str2);
String base64Img3 = Base64Helper.getFromBase64(base64Str3);
String base64Img4 = Base64Helper.getFromBase64(base64Str4);
//字符串处理 利用正则表达式找到首次出现“,”的索引
Matcher matcher1= Pattern.compile(",").matcher(base64Img1);
Matcher matcher2= Pattern.compile(",").matcher(base64Img2);
Matcher matcher3= Pattern.compile(",").matcher(base64Img3);
Matcher matcher4= Pattern.compile(",").matcher(base64Img4);
//转为二进制
byte[] bImg1 = null;
byte[] bImg2 = null;
byte[] bImg3 = null;
byte[] bImg4 = null;
if(matcher1.find()){
bImg1 = Base64.decodeBase64(base64Img1.substring(matcher1.start()+1));
}
if(matcher2.find()){
bImg2 = Base64.decodeBase64(base64Img2.substring(matcher2.start()+1));
}
if(matcher3.find()){
bImg3 = Base64.decodeBase64(base64Img3.substring(matcher3.start()+1));
}
if(matcher4.find()){
bImg4 = Base64.decodeBase64(base64Img4.substring(matcher4.start()+1));
}
Image img1 = Image.getInstance(bImg1);
Image img2 = Image.getInstance(bImg2);
Image img3 = Image.getInstance(bImg3);
Image img4 = Image.getInstance(bImg4);
img1.scaleToFit(120,260);
img2.scaleToFit(120,260);
img3.scaleToFit(120,260);
img4.scaleToFit(120,260);
img1.setAbsolutePosition(40,340);
img2.setAbsolutePosition(170,340);
img3.setAbsolutePosition(300,340);
img4.setAbsolutePosition(430,340);
cell = PDFUtil.mergeCol("处理结果:追缴金额" + prList.get(i).getAmount() + "元",textFont,7);
cell.setFixedHeight(200);
cell.setVerticalAlignment(Element.ALIGN_TOP);
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
cell.setPaddingTop(10);
cell.setPaddingLeft(10);
table.addCell(cell);
Paragraph p2 = new Paragraph("被调查人签字: 站长签字:",textFont);
p0.add(table);
document.add(p0);
document.add(p2);
document.add(img1);
document.add(img2);
document.add(img3);
document.add(img4);
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 关闭文档
document.close();
}
}
4、controller里面调用
/**
* 导出数据 生成pdf
* @param recordIds
* @param isGreen
* @param res
*/
@RequiresPermissions("sys:passRecord:export")
@RequestMapping("/export/{recordIds}/{isGreen}")
public void exportData(@PathVariable Long[] recordIds, @PathVariable int isGreen ,HttpServletResponse res) {
List<SysPassRecordEntity> list = queryListByIds(recordIds,isGreen);
try {
OutputStream os = res.getOutputStream();
res.setCharacterEncoding("utf-8");
res.setHeader("content-type", "application/octet-stream");
String date = DateUtils.format(new Date(),DateUtils.DATE_PATTERN);
if(isGreen == 1){
String fileName = URLEncoder.encode("绿通车辆资料" + date + ".pdf","UTF-8");
res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
GeneratePDF.createPDF1(os,list);
}
if(isGreen == 0){
String fileName = URLEncoder.encode("假冒绿通车辆资料" + date + ".pdf","UTF-8");
res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
GeneratePDF.createPDF0(os,list);
}
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
如有错误和建议,敬请指教
参考资料:Java操作PDF之iText超入门