近期项目中需要使用到下载pdf文档的操作,由于之前都没接触过,然后到网上查了下有两种选择OpenOffice和Itext。开始试了下OpenOffice,但是感觉太繁琐笨重,果断放弃了。后来就选用了Itext,总结起来六个字:简单,快捷,强大。话不多说上代码
(一)Pdf工具类
package com.datavessel.common.util;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
public class PdfUtil extends PdfPageEventHelper{
//创建一个document对象
Document document = new Document();
//页眉
public String header = "";
//文档字体大小,页脚页眉最好和文本大小一致
public int presentFontSize = 10;
//文档页面大小,最好前面传入,否则默认为A4纸张
public Rectangle pageSize = PageSize.A5;
//模板
public static PdfTemplate total;
//设置字体大小
public static Font headFont;
public static Font keyFont;
public static Font textFont;
public static Font infoFont;
public static Font spaceFont;
public static Font spaceFont1;
//定义基础字体
public static BaseFont bfChinese;
static{
try {
//解决中文显示问题
bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
headFont = new Font(bfChinese,22,Font.BOLD);
keyFont = new Font(bfChinese,16,Font.BOLD);
infoFont = new Font(bfChinese,14,Font.BOLD);
textFont = new Font(bfChinese,10,Font.NORMAL);
spaceFont = new Font(bfChinese,3,Font.NORMAL);
spaceFont1 = new Font(bfChinese,6,Font.NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
}
public PdfUtil(){
}
public PdfUtil(String yeMei, int presentFontSize, Rectangle pageSize) {
this.header = yeMei;
this.presentFontSize = presentFontSize;
this.pageSize = pageSize;
}
public static void addTitle(Document document,String title,Font font) throws DocumentException{
Paragraph t = new Paragraph(title,font);
//居中显示
t.setAlignment(1);
document.add(t);
}
public static void addSerTitle(Document document,String title,Font font) throws DocumentException{
document.add(new Paragraph(title,font));
}
public static void addDocument(Document document,String content,Font font) throws DocumentException{
document.add(new Paragraph(content,font));
}
public static void close(Document document) throws Exception{
document.close();
}
//文档打开时创建模板
public void onOpenDocument(PdfWriter writer, Document document) {
total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高
}
//关闭每页的时候,写入页眉,写入'第几页共'这几个字。
public void onEndPage(PdfWriter writer, Document document) {
// 1.写入页眉
ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase(header, textFont), document.left(), document.top() + 20, 0);
// 2.写入前半部分的 第 X页/共
int pageS = writer.getPageNumber();
String foot1 = "第 " + pageS + " 页 /共";
Phrase footer = new Phrase(foot1, textFont);
// 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len
float len = bfChinese.getWidthPoint(foot1, presentFontSize);
// 4.拿到当前的PdfContentByte
PdfContentByte cb = writer.getDirectContent();
// 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了 ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。
ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, footer, (document.rightMargin() + document.right() + document.leftMargin() - document.left() - len) / 2.0F + 20F, document.bottom() - 20, 0);
// 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F + len , y 轴和之前的保持一致,底边界-20
cb.addTemplate(total, (document.rightMargin() + document.right() + document.leftMargin() - document.left()) / 2.0F + 20F, document.bottom() - 20); // 调节模版显示的位置
}
public void onCloseDocument(PdfWriter writer, Document document) {
// 7.最后一步了,就是关闭文档的时候,将模板替换成实际的 Y 值,至此,page x of y 制作完毕,完美兼容各种文档size。
total.beginText();
total.setFontAndSize(bfChinese, presentFontSize);// 生成的模版的字体、颜色
String foot2 = " " + (writer.getPageNumber() - 1) + " 页";
total.showText(foot2);// 模版显示的内容
total.endText();
total.closePath();
}
public static void setFooter(PdfWriter writer) throws DocumentException, IOException {
//HeaderFooter headerFooter = new HeaderFooter(this);
//更改事件,瞬间变身 第几页/共几页 模式。
PdfUtil headerFooter = new PdfUtil();//就是上面那个类
writer.setBoxSize("art",PageSize.A4);
writer.setPageEvent(headerFooter);
}
private int pageHeight;
private int pageWidth;
public int getPageHeight() {
return pageHeight;
}
public void setPageHeight(int pageHeight) {
this.pageHeight = pageHeight;
}
public int getPageWidth() {
return pageWidth;
}
public void setPageWidth(int pageWidth) {
this.pageWidth = pageWidth;
}
private static int totalWidth = 330;
//--------------------------------------------
//创建PDF表格
//(一)
public static PdfPTable createTable(int colNumber){
PdfPTable table = new PdfPTable(colNumber);
try {
table.setTotalWidth(totalWidth); //设置表格的总宽度
table.setLockedWidth(true); //锁定宽度
table.setHorizontalAlignment(Element.ALIGN_CENTER); //对齐方式,左对齐
table.getDefaultCell().setBorder(1); //默认单元格的border为1
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
//(二)
public static PdfPTable createTable(float[] widths){
PdfPTable table = new PdfPTable(widths);
try {
table.setTotalWidth(totalWidth);
table.setLockedWidth(true);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
//创建单元格,可调整对其的格式
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));
return cell;
}
//创建无边框的单元格,可调整对其的格式
public static PdfPCell createNoBorderCell(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.setBorderWidth(0);
return cell;
}
//创建简单单元格
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));
return cell;
}
//创建单元格,可设置对齐格式和占用的列数
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;
}
}
(二)pdf表格文档添加的方法
//下载PDF报告
@RequestMapping("/pdf-download")
public ResponseEntity<byte[]> viewDownload(userModel model) throws Exception{
DvciCourtBadCredit credit = new DvciCourtBadCredit();
//获取下载pdf中的数据库中数据
creditInit(credit); //根据需求自己获取
userService.view(model); //根据需求自己获取
return userService.getPDFDownLoad(credit,model);
}
public ResponseEntity<byte[]> getPDFDownLoad(Credit credit,userModel model) throws Exception {
/*
* 创建一个document对象实例,
* 原方法:public document(Rectangle pageSize,int marginLeft,int marginRight,int marginTop,int marginBottom)
*/
Document document = new Document(PageSize.A4, 25, 25, 30, 30);
ByteArrayOutputStream baos = new ByteArrayOutputStream();//字节输出流
PdfWriter writer = PdfWriter.getInstance(document, baos);
PdfUtil.setFooter(writer);
writer.setFullCompression();
writer.setPdfVersion(PdfWriter.VERSION_1_4);
//打开文档
document.open();
//设置标题
//------为什么这里设置不了title等信息???????????????????????????
/*document.addTitle("pdf报告");
document.addAuthor("aaaaaaaa");
document.addCreationDate();
document.addCreator("bbbbbbbbb");*/
PdfUtil.addTitle(document, "pdf报告",PdfUtil.headFont);
PdfUtil.addDocument(document, " ",PdfUtil.keyFont); //空一行
//把数据库中内容写道pdf文档中
addCreditDocument(document,credit);
//关闭文档
document.close();
//创建输出字符流
byte[] content = baos.toByteArray();
return PdfDownload(content,model.getCustomerName());
}
public ResponseEntity<byte[]> PdfDownload(byte[] content,String name){
HttpHeaders headers = new HttpHeaders();
String fileName = "default";
try {
fileName = new String((name).getBytes("gbk"), "iso-8859-1");//设置中文格式
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//设置下载的pdf文件名全称(代后缀)
headers.setContentDispositionFormData("attachment", fileName+".pdf");
//设置返回下载的文件类型(pdf/vnd.ms-excel等)
headers.setContentType(new MediaType("application","pdf"));
return new ResponseEntity<byte[]>(content, headers, HttpStatus.OK);
}
public void addCreditDocument(Document document,Credit credit) throws DocumentException{
if(credit.getList()!=null){
PdfUtil.addSerTitle(document, "失信记录",PdfUtil.keyFont);
int i = 1;
for(Credit entity : credit.getList()){
PdfPTable table = PdfUtil.createTable(4);//穿件四列的table,一下每行必须有四个单元格,否则当前行无效
//设置每列的宽度
table.setTotalWidth(new float[]{140,210,80,160});
//table左对齐
table.setHorizontalAlignment(Element.ALIGN_LEFT);
PdfUtil.addDocument(document, i+":",PdfUtil.textFont);//当前table的序号标识
PdfUtil.addDocument(document, " ",PdfUtil.spaceFont); //空行space(美观,防止紧贴在一起)
table.addCell(PdfUtil.createCell("信息1:", PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell(entity.get******(), PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell("信息2:", PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell(entity.get******(), PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell("信息3:", PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell(entity.get******(), PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell("信息4:", PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell(entity.get******(), PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell("消息五:", PdfUtil.textFont, Element.ALIGN_LEFT));
table.addCell(PdfUtil.createCell(entity.get******(), PdfUtil.textFont, Element.ALIGN_LEFT,3));
document.add(table);
PdfUtil.addDocument(document, " ",PdfUtil.spaceFont);//空一行
i++;
}
}
}
以上分页查询转载:http://blog.csdn.net/ae6623/article/details/11734285