1.POI主要功能
可以操作office文檔的Java API
主要功能:操作excel文檔
? 雖然也可以操作word文檔,但功能比較差。Java中并沒有優秀的word解析技術。
? 解析word建議使用.net技術。Java利用WebService技術獲取解析結果。
? 為何要用專業組件來解析Excel?
? 因為Excel不是一個單純的文本格式。
與其他excel解析技術的比較:
? JXL:只能操作excel2003(現在也能操作2007-2016了)
? POI:可以操作整個office(excel,doc,vb宏,ppt,visio)
2.POI支持的解析方式
HSSF解析(.xls Excel97-03版本)
-
XSSF解析(.xlsx Excel07-16版本)
解析方式不同,是由于兩類版本excel文件本身的實現有不同
?
3.應用場景
-
導入excel數據
? 將excel中的備份數據還原到數據庫
-
導出excel數據
? 將數據庫中的數據導出或備份
?
4. 快速入門:
Maven坐標
<!--操作97-03版本用-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.11</version>
</dependency>
<!--操作07-16版本用-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.11</version>
</dependency>
<!--?-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.11</version>
</dependency>
實現步驟:
- 創建工作簿
- 創建sheet
- 創建行對象
- 創建單元格對象
- 設置內容
- 設置內容格式
? 使用wb去創建內容格式,是由于創建出的字體是在工作簿內公共使用的。- 設置字體
- 設置字體大小
- 創建cellStyle
- 將cellStyle賦給cell
- 將 工作簿寫入輸出流
- 下載
簡單Demo:
package cn.itcast.jx.poi;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class POITest {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
//1 創建工作薄:Workbook是一個接口,它有一個實現類HSSFWorkbook對象,這個對象專門操作excel97-03,excel的后綴名是xls
Workbook wb = new HSSFWorkbook();
//2 創建工作表sheet:工作表
Sheet sheet = wb.createSheet();
//3 創建行對象,java中從0開始計數
Row row = sheet.createRow(3);
//4 創建列對象
Cell cell = row.createCell(3);
//5 設置內容
cell.setCellValue("itcast,一統江湖");
//6 設置內容格式
Font font = wb.createFont();
font.setFontHeightInPoints((short)24);//以像素點的方式設置字體大小
font.setFontName("華文彩云");//設置字體
//System.out.println(Short.MIN_VALUE+"-"+Short.MAX_VALUE);
//創建格式
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setFont(font);
//將cellStyle給cell
cell.setCellStyle(cellStyle);
//7 保存(javase項目采用保存)
FileOutputStream stream = new FileOutputStream(new File("d://a.xls"));
wb.write(stream);//將對象寫進流
stream.flush();
stream.close();
//8 下載(web項目 才有下載)
System.out.println("運行結束");
}
}
項目應用Demo:出貨單打印:
package cn.itcast.jx.action.cargo;
import java.io.ByteArrayOutputStream;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.struts2.ServletActionContext;
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
import cn.itcast.jx.action.BaseAction;
import cn.itcast.jx.domain.ContractProduct;
import cn.itcast.jx.service.ContractProductService;
import cn.itcast.jx.util.DownloadUtil;
import cn.itcast.jx.util.UtilFuns;
/**
* 打印出貨表:選擇時間(船期)
*/
public class OutProductAction extends BaseAction {
//獲取頁面提交的打印月份
private String inputDate;
public String getInputDate() {
return inputDate;
}
public void setInputDate(String inputDate) {
this.inputDate = inputDate;
}
//跳轉到打印頁面
public String toedit() throws Exception {
return "toedit";
}
//依賴注入
private ContractProductService contractProductService;
public void setContractProductService(
ContractProductService contractProductService) {
this.contractProductService = contractProductService;
}
//打印excel文檔:
@SuppressWarnings("resource")
public String print() throws Exception {
//創建工作表
Workbook wb = new HSSFWorkbook();
//創建工作表
Sheet sheet = wb.createSheet();
//設置列寬
sheet.setColumnWidth(0, 6*256);
sheet.setColumnWidth(1, 26*256);
sheet.setColumnWidth(2, 12*256);
sheet.setColumnWidth(3, 30*256);
sheet.setColumnWidth(4, 12*256);
sheet.setColumnWidth(5, 15*256);
sheet.setColumnWidth(6, 10*256);
sheet.setColumnWidth(7, 10*256);
sheet.setColumnWidth(8, 10*256);
//定義一些公共變量
//行對象
Row nRow = null;
//單元格對象
Cell nCell = null;
//行號和列號
int rowNo = 0;
int cellNo = 1;
/************大標題的打印**************/
nRow = sheet.createRow(rowNo);
nCell = nRow.createCell(cellNo);
//橫向合并單元格
sheet.addMergedRegion(new CellRangeAddress(0,0,1,8));
//設置內容:
//設置內容:
/**
* 2012-01:
* 2012-10:
*
* 方式一:inputDate.replace("-0","-").replace("-","年")
* 方式二:inputDate.replace("-0","年").replace("-","年")
*
*/
nCell.setCellValue(inputDate.replace("-0","-").replace("-","年")+"月出貨表");
//行高?樣式?
nRow.setHeightInPoints(36f);
nCell.setCellStyle(bigTitle(wb));
/************小標題的打印**************/
//先換行
rowNo++;
//創建行對象
nRow = sheet.createRow(rowNo);
String[] titles = {"客戶","訂單號","貨號","數量","工廠","工廠交期","船期","貿易條款"};
//遍歷標題,進行輸出打印
for(String title:titles){
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(title);
nCell.setCellStyle(title(wb));
}
/************內容的打印**************/
//準備數據
//String hql = "from ContractProduct where contract.shipTime like '%"+inputDate+"%'";//mysql支持,oracle不支持
//hql中有to_char函數嗎?沒有,這是oracle中的pl/sql函數
//但是,hibernate強大的地方就在:你可以在HQL中使用數據庫中的函數
String hql = "from ContractProduct where to_char(contract.shipTime,'yyyy-mm') = '"+inputDate+"'";//oracle支持
//查詢:
List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);
//將數據放入sheet中
for(ContractProduct cp:list){
//行變化
rowNo++;
nRow = sheet.createRow(rowNo);
//列
cellNo = 1;//規1
//"客戶",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getCustomName());
nCell.setCellStyle(text(wb));
//"訂單號",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getContractNo());
nCell.setCellStyle(text(wb));
//"貨號",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getProductNo());
nCell.setCellStyle(text(wb));
//"數量",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getCnumber());
nCell.setCellStyle(text(wb));
//"工廠",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getFactoryName());
nCell.setCellStyle(text(wb));
//"工廠交期",
nCell = nRow.createCell(cellNo++);
//用SimpleDateFormat也行
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getDeliveryPeriod()));
nCell.setCellStyle(text(wb));
//"船期",
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getShipTime()));
nCell.setCellStyle(text(wb));
//"貿易條款"
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getTradeTerms());
nCell.setCellStyle(text(wb));
}
/************下載**************/
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//將內容寫入流
wb.write(byteArrayOutputStream);
//使用流
DownloadUtil downloadUtil = new DownloadUtil();
HttpServletResponse response = ServletActionContext.getResponse();
/**
* 第一個:文件流
* 第二個:response
* 第三個:下載的文件的名字
*/
downloadUtil.download(byteArrayOutputStream, response, "itcast.xls");
return NONE;
}
//大標題的樣式
public CellStyle bigTitle(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("宋體");
font.setFontHeightInPoints((short)16);
font.setBoldweight(Font.BOLDWEIGHT_BOLD); //字體加粗
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_CENTER); //橫向居中
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //縱向居中
return style;
}
//小標題的樣式
public CellStyle title(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("黑體");
font.setFontHeightInPoints((short)12);
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_CENTER); //橫向居中
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //縱向居中
style.setBorderTop(CellStyle.BORDER_THIN); //上細線
style.setBorderBottom(CellStyle.BORDER_THIN); //下細線
style.setBorderLeft(CellStyle.BORDER_THIN); //左細線
style.setBorderRight(CellStyle.BORDER_THIN); //右細線
return style;
}
//文字樣式
public CellStyle text(Workbook wb){
CellStyle style = wb.createCellStyle();
Font font = wb.createFont();
font.setFontName("Times New Roman");
font.setFontHeightInPoints((short)10);
style.setFont(font);
style.setAlignment(CellStyle.ALIGN_LEFT); //橫向居左
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //縱向居中
style.setBorderTop(CellStyle.BORDER_THIN); //上細線
style.setBorderBottom(CellStyle.BORDER_THIN); //下細線
style.setBorderLeft(CellStyle.BORDER_THIN); //左細線
style.setBorderRight(CellStyle.BORDER_THIN); //右細線
return style;
}
}
5.使用模板的實現
? 模板即是一個已經設置好部分樣式的excel文檔。
? 標題行,列寬行高,字體顏色等可以在模板中先設置好。
步驟
制作模板文件
-
讀取模板文件,獲取工作簿
//路徑 String path = ServletActionContext.getRequest().getRealPath("/"); path += "/make/xlsprint/tOUTPRODUCT.xls"; //輸入流 FileInputStream is = new FileInputStream(new File(path)); //借助模板創建工作簿 Workbook wb = new HSSFWorkbook(is);
-
獲取sheet
Sheet sheet = wb.getSheetAt(0);
獲取行
-
獲取某單元格的格式
CellStyle customerCellStyle = nRow.getCell(cellNo++).getCellStyle();
設置內容及格式
將工作簿寫入輸出流
下載
項目應用Demo:
@SuppressWarnings("resource")
public String print() throws Exception {
//讀取模板,路徑
String path = ServletActionContext.getRequest().getRealPath("/");
path += "/make/xlsprint/tOUTPRODUCT.xls";//獲取模板在服務器的路徑
FileInputStream is = new FileInputStream(new File(path));
//1 借助模板創建工作簿
Workbook wb = new HSSFWorkbook(is);
//2 獲取工作表
Sheet sheet = wb.getSheetAt(0);
//定義公共變量
Row nRow = null;//行對象
Cell nCell = null;//單元格對象
int rowNo = 0;//第幾行
int cellNo = 1;//列對象
/*******************設置大標題********************/
//3 獲取行對象
nRow = sheet.getRow(rowNo);
//4 獲取單元格
nCell = nRow.getCell(cellNo);
// 5 設置數據
nCell.setCellValue(inputDate.replace("-0", "-").replace("-", "年")+"月份出貨表");
// 6 設置樣式,獲取原來的樣式賦值,這步可以省略
//nCell.setCellStyle(nCell.getCellStyle());
/*******************設置小標題********************/
rowNo++;//跳過小標題行,因為模板中已經設置好
/*******************設置出貨數據********************/
rowNo++;//進入數據第一行行
//獲取樣式
nRow = sheet.getRow(rowNo);
//客戶
CellStyle customerCellStyle = nRow.getCell(cellNo++).getCellStyle();
//訂單號
CellStyle contractNoCellStyle = nRow.getCell(cellNo++).getCellStyle();
//貨號
CellStyle productNoCellStyle = nRow.getCell(cellNo++).getCellStyle();
//數量
CellStyle cnumberCellStyle = nRow.getCell(cellNo++).getCellStyle();
//工廠
CellStyle factoryCellStyle = nRow.getCell(cellNo++).getCellStyle();
//工廠交期
CellStyle deliveryPeriodCellStyle = nRow.getCell(cellNo++).getCellStyle();
//船期
CellStyle shipTimeCellStyle = nRow.getCell(cellNo++).getCellStyle();
//貿易條款
CellStyle tradeTermsCellStyle = nRow.getCell(cellNo++).getCellStyle();
// 準備數據
//mysql方式(oracle不支持):
//String hql = "from ContractProduct where contract.shipTime like '%"+inputDate+"%'";
//Oracle方式:to_char可以將Date轉成varchar,oracle中的所有的PL/SQL函數都可以直接寫在hql語句中
String hql = "from ContractProduct where to_char(contract.shipTime,'yyyy-mm')='"+inputDate+"'";
//從數據庫查找要輸出的貨物的集合
List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);
for(ContractProduct cp:list){
//單元格no歸1
cellNo = 1;
//一條數據創建一行
nRow = sheet.createRow(rowNo);
//創建每列的數據
//客戶
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getCustomName());
nCell.setCellStyle(customerCellStyle);
//訂單號
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getContractNo());
nCell.setCellStyle(contractNoCellStyle);
//貨號
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getProductNo());
nCell.setCellStyle(productNoCellStyle);
//數量
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getCnumber());
nCell.setCellStyle(cnumberCellStyle);
//工廠
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getFactoryName());
nCell.setCellStyle(factoryCellStyle);
//工廠交期
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getDeliveryPeriod()));
nCell.setCellStyle(deliveryPeriodCellStyle);
//船期
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getShipTime()));
nCell.setCellStyle(shipTimeCellStyle);
//貿易條款
nCell = nRow.createCell(cellNo++);
nCell.setCellValue(cp.getContract().getTradeTerms());
nCell.setCellStyle(tradeTermsCellStyle);
//切到下一行,準備下一行數據操作
rowNo++;
}
/***************************************************/
// 7.寫入流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();//字節數組緩沖流
wb.write(byteArrayOutputStream);
// 8.下載
DownloadUtil downloadUtil = new DownloadUtil();
HttpServletResponse response = ServletActionContext.getResponse();
/**
* 第一個參數:流
* 第二個參數:response
* 第三個參數:下載的文件名
*/
downloadUtil.download(byteArrayOutputStream, response, "出貨表.xls");
return NONE;
}