PDF格式報表生成 (IText技術)
1. IText基本介紹
官網: http://itextpdf.com/ 最新iText7 涉及商業收費
匯入iText報表jar
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>com.itextpdf</ groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
new 5.x+
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
< dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
1.2 IText基礎使用
參考書籍:《[iText實戰(第2版)].(iText.in.Action).Bruno.Lowagie.文字版.pdf》,在ReportAction 新增 exportPdf 方法
生成PDF五步
生成步驟:
1 建立Document文件
2 建立輸出位置
3 開啟文件
4 寫入內容
5 關閉文件
package com.czxy.itext;
import com.itextpdf.awt.AsianFontMapper;
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.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Fang
* @create 2018-10-12 21:50
* @desc
**/
public class TestItext {
public static void main(String[] args) throws Exception{
// 建立一個文件
Document document = new Document();
// 設定輸出位置
PdfWriter.getInstance(document,new FileOutputStream(new File("d:\\a.pdf")));
// 開啟文件
document.open();
// 寫入內容
document.add(new Paragraph("czdx,一統江湖,千秋萬代"));
// 關閉文件
document.close();
}
}
這裡注意:中文是無法生成到pdf的
需要設定字型(設定可以支援中文的字型檔 【作業系統】 , 【匯入itext-asian的jar包】)
座標:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
package com.czxy.itext;
import com.itextpdf.awt.AsianFontMapper;
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.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Fang
* @create 2018-10-12 21:50
* @desc
**/
public class TestItext {
public static void main(String[] args) throws Exception {
//2 建立pdf物件
Document document = new Document();
//3 設定輸出位置
// 第一個引數:文件物件
// 第二個引數:輸出位置
PdfWriter.getInstance(document,new FileOutputStream(new File("d:\\a.pdf")));
//4 開啟文件
document.open();
//5 寫入內容
// 建立BaseFont 基礎字型物件
// String name, 字型名字:宋體,楷體,隸書 AsianFontMapper.ChineseSimplifiedFont : STSong-Light
// String encoding:編碼 + 佈局方式
// boolean embedded:是否內嵌字型 true 匯出的時候將字型一併匯出去 false 不匯出字型
BaseFont baseFont = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, false);
//BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
// 通過基礎字型建立字型
/**
* 第一個引數:baseFont
* 第二個引數:字型大小
* 3 :字型樣式 加粗 切斜 加粗傾斜 正常.....
* 4 :字型顏色
*/
Font font = new Font(baseFont,16,Font.BOLDITALIC,BaseColor.BLUE);
document.add(new Paragraph("czdx,一統江湖,千秋萬代,yi tong jiang hu",font));
//6 關閉文件
document.close();
}
}
閱讀:
中文的輸出是Java本身的問題,為了解決中文的輸出問題,需要多下載一個名為iTextAsian.jar的類庫檔案。該檔案的下載地址為“http://prdownloads.sourceforge.net/itext/iText Asian.jar”。這個類庫檔案定義了與中文輸出相關的一些檔案。
為了輸出中文,可以通過以下程式碼進行解決:
BaseFont bfChinese = BaseFont.createFont(“STSong-Light”, “UniGB-UCS2-H”, BaseFont.NOT_EMBEDDED);
在上述程式碼中,定義了中文的基礎字型。其中,“STSong-Light”定義了使用的中文字型,iTextAsian.jar類庫中提供了幾個可供使用的字型,都是以properties結尾的檔案。“UniGB-UCS2-H”定義文字的編碼標準和樣式,GB代表編碼方式為gb2312,H代表橫排字,V代表豎排字,iTextAsian.jar類庫中以cmap結尾的幾個檔案都是關於編碼和樣式定義的。
1.3 IText進階使用
code:
package com.czxy.bos.itextpdf;
import com.itextpdf.awt.AsianFontMapper;
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.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
public class ITextTest03 {
public static void main(String[] args) throws Exception{
// 準備資料
List<Object[]> list = new ArrayList<>();
list.add(new Object[]{"月份","去年銷量","今年銷量"});
list.add(new Object[]{"七月份",1000,1500});
list.add(new Object[]{"八月份",1200,1300});
list.add(new Object[]{"九月份",900,1100});
//1 建立文件物件
Document document = new Document();
//2 設定輸出位置
PdfWriter.getInstance(document,new FileOutputStream(new File("d:\\出貨表.pdf")));
//3 開啟文件
document.open();
//4 輸出內容
// 建立基礎字型支援中文
BaseFont baseFont = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, false);
/****大標題輸出******/
Font titleFont = new Font(baseFont, 30, Font.BOLD, BaseColor.RED);
// 居中
Paragraph bigTitleParagraph = new Paragraph("出貨表", titleFont);
bigTitleParagraph.setAlignment(Paragraph.ALIGN_CENTER);
document.add(bigTitleParagraph);
/****作者輸出******/
Font authorFont = new Font(baseFont, 15, Font.NORMAL, BaseColor.BLACK);
Paragraph authorParagraph = new Paragraph("傳智學院", authorFont);
authorParagraph.setAlignment(Paragraph.ALIGN_RIGHT);
document.add(authorParagraph);
/****表格輸出******/
Font contentFont = new Font(baseFont, 15, Font.NORMAL, BaseColor.BLUE);
// 引數:列數
PdfPTable table = new PdfPTable(3);
// 迴圈資料
for(Object[] values:list){
table.addCell(new PdfPCell(new Phrase(values[0].toString(),contentFont)));
table.addCell(new PdfPCell(new Phrase(values[1].toString(),contentFont)));
table.addCell(new PdfPCell(new Phrase(values[2].toString(),contentFont)));
}
// 設定元素距離上一個元素的距離
table.setSpacingBefore(10);
// 將表格新增到文件中
document.add(table);
//5 關閉文件
document.close();
}
}
1.4 IText整合專案
1、在頁面 waybill_manage.html 提供 pdf匯出按鈕
<a id="exportPdfBtn" icon="icon-print" href="#" class="easyui-linkbutton" plain="true">匯出PDF報表</a>
新增JS提交的按鈕
// 匯出 PDF 按鈕
$("#exportPdfBtn").click(function(){
// 下載效果
// $("#searchForm").attr("action", "/report/exportPdf.html");
// $("#searchForm").submit();
location.href="/pdf/exportPdf";
});
2、在PDFController中新增exportPdf的方法
為什麼此處需要建立PDFController?
答:如果寫在RepostController中的話,POI的包和IText的包衝突
package com.czxy.bos.controller.print;
import com.czxy.bos.domain.take_delivery.WayBill;
import com.czxy.bos.service.take_delivery.WayBillService;
import com.czxy.bos.util.DownloadUtil;
import com.itextpdf.awt.AsianFontMapper;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.List;
@RestController
@RequestMapping("/pdf")
public class PDFController {
@Autowired
private WayBillService wayBillService;
@GetMapping("/exportPdf")
public void exportPdf(HttpServletResponse response) throws Exception{
//1 查詢資料
List<WayBill> wayBillList = wayBillService.findAllWayBill();
//2 建立document文件
Document document = new Document();
// 建立流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//3 設定輸出位置--將document寫進流
PdfWriter.getInstance(document,byteArrayOutputStream);
//4 開啟文件
document.open();
//5 寫入內容
BaseFont baseFont = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, false);
/****************/
Font titleFont = new Font(baseFont, 12, Font.BOLD, BaseColor.BLACK);
// 建立表格
PdfPTable table = new PdfPTable(9);
String[] titles={"編號id","運單編號","訂單編號","寄件人姓名","寄件人電話","寄件人地址","收件人姓名","收件人電話","收件人地址"};
for (String title:titles){
table.addCell(new PdfPCell(new Phrase(title,titleFont)));
}
for (WayBill wayBill:wayBillList){
table.addCell(new PdfPCell(new Phrase(wayBill.getId()+"",titleFont)));
table.addCell(new PdfPCell(new Phrase(wayBill.getWayBillNum(),titleFont)));
table.addCell(new PdfPCell(new Phrase(wayBill.getOrderId()+"",titleFont)));
table.addCell(new PdfPCell(new Phrase(wayBill.getSendName(),titleFont)));
table.addCell(new PdfPCell(new Phrase(wayBill.getSendMobile(),titleFont)));
table.addCell(new PdfPCell(new Phrase(wayBill.getSendAddress(),titleFont)));
table.addCell(new PdfPCell(new Phrase(wayBill.getRecName(),titleFont)));
table.addCell(new PdfPCell(new Phrase(wayBill.getRecMobile(),titleFont)));
table.addCell(new PdfPCell(new Phrase(wayBill.getRecAddress(),titleFont)));
}
// 將表格寫進文件中
document.add(table);
//6 關閉文件
document.close();
//7 下載
DownloadUtil downloadUtil = new DownloadUtil();
downloadUtil.download(byteArrayOutputStream,response,"報表.pdf");
}
DownloadUtil.java
package com.czxy.bos.util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
public class DownloadUtil {
/**
* @param filePath 要下載的檔案路徑
* @param returnName 返回的檔名
* @param response HttpServletResponse
* @param delFlag 是否刪除檔案
*/
protected void download(String filePath,String returnName,HttpServletResponse response,boolean delFlag){
this