poiExcel表格所有操作以及資料匯入匯出
這個是本人在學習中記錄的筆記以供大家參考
- Poi簡介:
1.1什麼是poi
Apache POI [1] 是用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。POI為“Poor Obfuscation Implementation”的首字母縮寫,意為“簡潔版的模糊實現”。
1.2poi結構
HSSF [1] - 提供讀寫Microsoft Excel XLS格式檔案的功能。
XSSF [1] - 提供讀寫Microsoft Excel OOXML
HWPF [1] - 提供讀寫Microsoft Word DOC格式檔案的功能。
HSLF [1] - 提供讀寫Microsoft PowerPoint格式檔案的功能。
HDGF [1] - 提供讀Microsoft Visio格式檔案的功能。
HPBF [1] - 提供讀Microsoft Publisher格式檔案的功能。
HSMF [1] - 提供讀Microsoft Outlook
這些都是poi提供的一些包
1.3:下載地址
這個是最新的jar包,4.0的
https://www.apache.org/dyn/closer.lua/poi/release/bin/poi-bin-4.0.0-20180907.tar.gz
還有原始碼包的下載
https://www.apache.org/dyn/closer.lua/poi/release/src/poi-src-4.0.0-20180907.tar.gz
下載點選這個
1.4:常用類說明
類名 說明
HSSFWorkbook Excel的文件物件
HSSFSheet sheet頁
Excel的表單
HSSFRow
Excel的行
HSSFCell
Excel的格子單元
HSSFFont Excel字型
HSSFDataFormat 格子單元的日期格式
HSSFHeader Excel文件Sheet的頁首
HSSFFooter Excel文件Sheet的頁尾
HSSFCellStyle 格子單元樣式
HSSFDateUtil 日期
HSSFPrintSetup 列印
HSSFErrorConstants 錯誤資訊表
- poi基礎
- 新建一個表格
首先要將下載好的jar包,解壓將根目錄下的所有包,以及將lib目錄下的commons-logging-1.2.jar
和junit-4.12.jar以及log4j-1.2.17.jar這三個通用包匯入到專案的lib的目錄下,poi-4.0.0.jar包是最
重要的。
主要介紹HSSFWorkbook
/**
* 多型實現
* HSSFWorkbook 是對於xls進行操作
*/
Workbook wb=new HSSFWorkbook();//新建一個工作簿
/**
* 匯出所以用到輸出流
*引數為輸出的地址
*/
FileOutputStream fout=new FileOutputStream("E:\\Demo\\poi.xls");
wb.write(fout);//Workbook提供了write的方法
fout.close();//將輸出流關閉
2.1.1新建sheet頁
在新建工作簿的基礎上新建sheet頁,wb.createSheet() 返回一個Sheet()如果不進行操作不用接收
/**
* 多型實現
* HSSFWorkbook 是對於xls進行操作
*/
Workbook wb=new HSSFWorkbook();//新建一個工作簿
/**
* 匯出所以用到輸出流
*/
FileOutputStream fout=new FileOutputStream("E:\\Demo\\poi.xls");
/**
* 有有參和無引數兩種
* 引數為sheet頁的名字
* 不寫引數預設名字為sheet0到n
*/
Sheet sheet1 = wb.createSheet();//建立一個sheet頁
Sheet sheet2 = wb.createSheet("第二個sheet頁");//建立第二個sheet頁
wb.write(fout);
fout.close();//將輸出流關閉
一些工作表的方法
workbook.setActiveSheet(工作表下標);//設定預設工作表
workbook.setSheetName(2(工作表下標), "1234"(新名字));//重新命名工作表
sheet1.setZoom(1,2);//50%顯示比例
sheet2.setZoom(2,1);//200%顯示比例
sheet3.setZoom(1,10);//10%顯示比例
顯示/隱藏網格線
HSSFWorkbook workbook = new HSSFWorkbook();// 建立Excel檔案(Workbook)
HSSFSheet sheet1= workbook.createSheet("Test0");// 建立工作表(Sheet)
HSSFSheet sheet2=workbook.createSheet("Test1");// 建立工作表(Sheet)
sheet1.setDisplayGridlines(false);//隱藏Excel網格線,預設值為true
sheet2.setGridsPrinted(true);//列印時顯示網格線,預設值為false
2.1.2新建行和列
建立行要在sheet頁的基礎上,單元格在行的基礎上建立,每一行一個行物件Row
對於單元格賦值cell物件setCellValue()就可以,而且行和單元格的建立都從0 開始
列的值可以設定的型別也比較多樣 int double String boolean Date 等都是可以的
Workbook wb=new HSSFWorkbook();//新建一個工作簿
FileOutputStream fout=new FileOutputStream("E:\\Demo\\poi.xls");
Sheet sheet= wb.createSheet("第一個sheet頁");//建立一個sheet頁
Row row=sheet.createRow(0); // 建立一個行 第一行
Cell cell=row.createCell(0); // 建立一個單元格 第1列
/**
* 給單元格設定值
*值型別可以為int double String boolean
*還有Date等
*/
cell.setCellValue(1);
row.createCell(1).setCellValue(1.2);//建立第一行第二個單元格
row.createCell(2).setCellValue("這是一個單元格");//建立第一行第三個單元格
row.createCell(3).setCellValue(false);//建立第一行第四個單元格
/**
* HSSFCell一些靜態常量
* short型別和int型別
*/
row.createCell(4).setCellValue(HSSFCell.ENCODING_COMPRESSED_UNICODE);
/**
* 第二個行 每一行需要一個行物件
* 所以需要儲存一個行物件
*/
Row row1 = sheet.createRow(1);
row1.createCell(0).setCellValue("第二行第一列");
row1.createCell(1).setCellValue(true);
row1.createCell(2).setCellValue("第二行第三列");
row1.createCell(3).setCellValue("第二行第四列");
wb.write(fout);//輸出
fout.close();
2.1.2.1組合行列
HSSFSheet sheet= workbook.createSheet("Test0");// 建立工作表(Sheet)
sheet.groupRow(1, 3);//組合行
sheet.groupRow(2, 4);//組合行
sheet.groupColumn(2, 7);//組合列
這裡簡單的介紹一下什麼叫做組合:組合分為行組合和列組合,所謂行組合,就是讓n行組合成一個集合,能夠進行展開和合攏操作。
使用POI也可以取消組合,例如:sheet.ungroupColumn(1, 3);//取消列組合
2.1.2.2鎖定列
在Excel中,有時可能會出現列數太多或是行數太多的情況,這時可以通過鎖定列來凍結部分列,不隨滾動條滑動,方便檢視。
HSSFSheet sheet= workbook.createSheet("Test0");// 建立工作表(Sheet)
sheet.createFreezePane(2, 3, 15, 25);//凍結行列
下面對CreateFreezePane的引數作一下說明:
第一個引數表示要凍結的列數;
第二個引數表示要凍結的行數,這裡只凍結列所以為0;
第三個引數表示右邊區域可見的首列序號,從1開始計算;
第四個引數表示下邊區域可見的首行序號,也是從1開始計算,這裡是凍結列,所以為0;
2.1.2.3上下移動行
FileInputStream stream = new FileInputStream(filePath);
HSSFWorkbook workbook = new HSSFWorkbook(stream);
HSSFSheet sheet = workbook.getSheet("Test0");
sheet.shiftRows(2, 4, 2);//把第3行到第4行向下移動兩行
HSSFSheet.shiftRows(startRow, endRow, n)引數說明
startRow:需要移動的起始行;
endRow:需要移動的結束行;
n:移動的位置,正數表示向下移動,負數表示向上移動;
2.1.3建立文件摘要資訊
這裡只是抽取了關鍵程式碼,這個是給檔案設定一些摘要資訊
HSSFWorkbook wb = new HSSFWorkbook();// 新建一個工作簿
wb.createInformationProperties();//建立文件資訊
DocumentSummaryInformation dsi= wb.getDocumentSummaryInformation();//摘要資訊
dsi.setCategory("類別:Excel檔案");//類別
dsi.setManager("管理者:花花");//管理者
dsi.setCompany("公司:zking");//公司
SummaryInformation si = wb.getSummaryInformation();//摘要資訊
si.setSubject("主題:--");//主題
si.setTitle("標題:測試文件");//標題
si.setAuthor("作者:花花");//作者
si.setComments("備註:POI測試文件");//備註
結果為:
2.1.4建立表格批註資訊
HSSFWorkbook wb = new HSSFWorkbook();
FileOutputStream fout = new FileOutputStream("E:\\Demo\\poi.xls");
HSSFSheet sheet = wb.createSheet("工作表名");// 建立工作表(Sheet頁)
HSSFPatriarch patr = sheet.createDrawingPatriarch();
HSSFClientAnchor anchor = patr.createAnchor(0, 0, 0, 0, 5, 1, 8, 3);// 建立批註位置
HSSFComment comment = patr.createCellComment(anchor);// 建立批註
comment.setString(new HSSFRichTextString("這是一個批註段落!"));// 設定批註內容
comment.setAuthor("花花");// 設定批註作者
comment.setVisible(true);// 設定批註預設顯示
HSSFCell cell = sheet.createRow(2).createCell(1);
cell.setCellValue("測試");
cell.setCellComment(comment);// 把批註賦值給單元格
wb.write(fout);
建立批註位置HSSFPatriarch.createAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2)方法引數說明:
- dx1 第1個單元格中x軸的偏移量
- dy1 第1個單元格中y軸的偏移量
- dx2 第2個單元格中x軸的偏移量
- dy2 第2個單元格中y軸的偏移量
- col1 第1個單元格的列號
- row1 第1個單元格的行號
- col2 第2個單元格的列號
- row2 第2個單元格的行號
也就是:
2.1.5 建立頁首和頁尾
HSSFWorkbook wb = new HSSFWorkbook();
FileOutputStream fout = new FileOutputStream("E:\\Demo\\poi.xls");
HSSFSheet sheet = wb.createSheet("Test");// 建立工作表(Sheet)
HSSFHeader header =sheet.getHeader();//得到頁首
header.setLeft("頁首左邊");
header.setRight("頁首右邊");
header.setCenter("頁首中間");
String tab = HSSFHeader.tab();//表名
System.out.println(tab);
HSSFFooter footer =sheet.getFooter();//得到頁尾
footer.setLeft("頁尾左邊");
footer.setRight("頁尾右邊");
footer.setCenter("頁尾中間");
wb.write(fout);
fout.close();
也可以使用Office自帶的標籤定義,你可以通過HSSFHeader或HSSFFooter訪問到它們,都是靜態屬性,列表如下:
- HSSFHeader.tab &A 表名
- HSSFHeader.file &F 檔名
- HSSFHeader.startBold &B 粗體開始
- HSSFHeader.endBold &B 粗體結束
- HSSFHeader.startUnderline &U 下劃線開始
- HSSFHeader.endUnderline &U 下劃線結束
- HSSFHeader.startDoubleUnderline &E 雙下劃線開始
- HSSFHeader.endDoubleUnderline &E 雙下劃線結束
- HSSFHeader.time &T 時間
- HSSFHeader.date &D 日期
- HSSFHeader.numPages &N 總頁面數
- HSSFHeader.page &P 當前頁號
2.1.6 時間格式的單元格
由於很多程式碼都是重複的也出現了多次我在這,也就不寫在筆記裡了,只摘取了關鍵部分
CreationHelper 一個小工具類,使用工作簿建立Workbook getCreationHelper()
CellStyle 單元格的樣式類,也是使用Workbook建立createCellStyle()
Row row=sheet.createRow(0); // 建立一個行 第一行
Cell cell=row.createCell(0); // 建立一個單元格 第1列
cell.setCellValue(new Date());
/**
* 小工具
* 使用工作簿獲取
*/
CreationHelper creationHelper=wb.getCreationHelper();
/**
* 單元格樣式類
* 使用工作簿Workbook建立
*/
CellStyle cellStyle=wb.createCellStyle();
/**
* 設定時間的顯示格式
*/
cellStyle.setDataFormat(creationHelper.createDataFormat().getFormat("yyyy-mm-dd :hh:mm:ss"));
cell=row.createCell(1);//建立第二列
cell.setCellValue(new Date());
/**
* 設定單元格的格式
*/
cell.setCellStyle(cellStyle);
/**
* 第三列和第二列的效果是一樣的
*/
cell=row.createCell(2);//建立第三列
/**
* Calendar 日曆類 也可以用來獲取時間
*/
cell.setCellValue(Calendar.getInstance());
cell.setCellStyle(cellStyle);
2.2.1讀取工作簿
獲取單元格的內容主要是要區分每個單元格的值型別,不然會報錯的,而且4.0和3.9有很大的區別一定要注意版本之間的差別,
public static void main(String[] args) throws IOException {
FileInputStream fins=new FileInputStream("E:\\Demo\\好氣呀沒事改什麼版本.xls");
/**
* poi檔案系統 可以接收入一個輸入流
*/
POIFSFileSystem pfs=new POIFSFileSystem(fins);
/**
* 建立一個工作簿
* 因為HSSFWorkbook實現了介面而且有了接口裡沒有的方法
* 所以用這個
*/
HSSFWorkbook wb=new HSSFWorkbook(pfs);
/**
* 獲取第一個sheet頁
*/
HSSFSheet sheetAt = wb.getSheetAt(0);
/**
* 如果不存在sheet頁就return
*/
if(sheetAt==null) {
return;
}
/**
* 遍歷當前的sheet頁裡面的行
* sheetAt.getLastRowNum() 獲取到最後一行的位置
*/
for(int rowIndex=0;rowIndex<=sheetAt.getLastRowNum();rowIndex++){
/**
* 獲取當前的行物件
*/
HSSFRow hssfRow = sheetAt.getRow(rowIndex);//獲取到當前行的物件
if(hssfRow==null){
continue;
}
/**
* 同理遍歷當前行裡的所有列
* hssfRow.getLastCellNum()
* 獲取到最後一列的位置
*/
for(int cellNum=0;cellNum<=hssfRow.getLastCellNum();cellNum++){
HSSFCell hssfCell=hssfRow.getCell(cellNum);//獲取到列物件
if(hssfCell==null){
continue;
}
/**
* 呼叫值處理的方法
*/
System.out.print(" "+getValue(hssfCell));
}
/**
* 換行的效果
*/
System.out.println();
}
}
/**
*
* @Title: getValue
* @Description: (判斷單元格物件的值型別 這是3.9版本的寫法)
* @param hssfCell
* @return
* @return String
*/
private static String getValue(HSSFCell hssfCell){
/**
* 值型別的常量值
* HSSFCell.CELL_TYPE_BOOLEAN
*/
if(hssfCell.getCellType()==HSSFCell.CELL_TYPE_BOOLEAN){
return String.valueOf(hssfCell.getBooleanCellValue());
}else if(hssfCell.getCellType()==HSSFCell.CELL_TYPE_NUMERIC){
/**
* 小的工具類 判斷此單元格是不是時間格式
*/
if(HSSFDateUtil.isCellDateFormatted(hssfCell)){
/**
* 取到的時候數字
* 因為時間格式不能顯示給人家數字所以轉換
* 轉換格式
*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue()));
}
return String.valueOf(hssfCell.getNumericCellValue());
} else{
return String.valueOf(hssfCell.getStringCellValue());
}
}
/**
* s
* @Title: getValue
* @Description: (從單元格內判斷取值 這是4.0版本的寫法)
* @param hssfCell
* @return
* @return String
*/
public static String getValue(HSSFCell hssfCell) {
/**
* 這裡獲取到的是String型別的常量值還是有變化的
*/
if(hssfCell.getCellType()==CellType.BOOLEAN){
return String.valueOf(hssfCell.getBooleanCellValue());
}else if(hssfCell.getCellType()==CellType.NUMERIC){
/**
* 小的工具類 判斷此單元格是不是時間格式
*/
if(HSSFDateUtil.isCellDateFormatted(hssfCell)){
/**
* 轉換格式
*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue()));
}
return String.valueOf(hssfCell.getNumericCellValue());
} else{
return String.valueOf(hssfCell.getStringCellValue());
}
}
2.2.2文字提取
ExcelExtractor 直接抽取EXcel裡的內容為文字,可以設定sheet頁的名字是否展示
public static void main(String[] args) throws IOException {
FileInputStream fins=new FileInputStream("E:\\Demo\\好氣呀沒事改什麼版本.xls");
POIFSFileSystem pfs=new POIFSFileSystem(fins);
HSSFWorkbook wb=new HSSFWorkbook(pfs);
/**
* 抽取Excel裡的內容為文字
*/
ExcelExtractor extractor=new ExcelExtractor(wb);
extractor.setIncludeSheetNames(false);//不獲取sheet頁的名字
System.out.println(extractor.getText());
}
2.2.3內容讀取與重寫
FileInputStream fins = new FileInputStream("E:\\Demo\\好氣呀沒事改什麼版本.xls");
POIFSFileSystem pfs = new POIFSFileSystem(fins);
HSSFWorkbook wb = new HSSFWorkbook(pfs);
HSSFSheet sheet=wb.getSheetAt(0); // 獲取第一個Sheet頁
Row row=sheet.getRow(0); // 獲取第一行
Cell cell=row.getCell(0); // 獲取單元格
if(cell==null){
cell=row.createCell(3);// 如果為空自己建立一個
}
cell.setCellType(Cell.CELL_TYPE_STRING);//設定獲取到的值型別
cell.setCellValue("測試單元格");// 修改此單元格內的值
HSSFRow createRow = sheet.createRow(2);// 手動建立一個新的單元格
createRow.createCell(0).setCellValue("手動新增");
FileOutputStream fout = new FileOutputStream("E:\\Demo\\poi.xls");
wb.write(fout);
fout.close();
System.out.println("好了");
2.3.1單元格樣式
主要是單元格的對齊樣式
/**
* 建立一個單元格併為其設定指定的對其方式
*
* @param wb 工作簿
* @param row 行
* @param column 列
* @param halign 水平方向對其方式
* @param valign 垂直方向對其方式
*/
private static void createCell(Workbook wb, Row row, short column, short halign, short valign) {
Cell cell = row.createCell(column); // 建立單元格
cell.setCellValue(new HSSFRichTextString("Align It")); // 設定值為了效果 默認了
CellStyle cellStyle = wb.createCellStyle(); // 建立單元格樣式
cellStyle.setAlignment(halign); // 設定單元格水平方向對其方式
cellStyle.setVerticalAlignment(valign); // 設定單元格垂直方向對其方式
cell.setCellStyle(cellStyle); // 設定單元格樣式
}
public static void main(String[] args) throws IOException {
Workbook wb = new HSSFWorkbook();// 新建一個工作簿
FileOutputStream fout = new FileOutputStream("E:\\Demo\\poi.xls");
Sheet sheet = wb.createSheet("第一個sheet頁");// 建立一個sheet頁
Row row = sheet.createRow(2); // 建立一個行
/**
* 可以設定行高
*/
row.setHeightInPoints(30);// 設定行高
/**
* 這裡的常量樣式還是很多的 主要使用的就是這幾種
*/
createCell(wb, row, (short) 0, HSSFCellStyle.ALIGN_CENTER, HSSFCellStyle.VERTICAL_BOTTOM);
createCell(wb, row, (short) 1, HSSFCellStyle.ALIGN_FILL, HSSFCellStyle.VERTICAL_CENTER);
createCell(wb, row, (short) 2, HSSFCellStyle.ALIGN_LEFT, HSSFCellStyle.VERTICAL_TOP);
createCell(wb, row, (short) 3, HSSFCellStyle.ALIGN_RIGHT, HSSFCellStyle.VERTICAL_TOP);
wb.write(fout);
fout.close();
}
水平對齊相關引數
1.如果是居中對齊就是 HSSFCellStyle.ALIGN_CENTER;
2.如果是右側對齊就是 HSSFCellStyle.ALIGN_RIGHT;
3.如果是跨列舉中就是 HSSFCellStyle.ALIGN_CENTER_SELECTION;
4.如果是兩端對齊就是 HSSFCellStyle.ALIGN_JUSTIFY;
5.如果是填充就是 HSSFCellStyle.ALIGN_FILL;
垂直對齊相關引數
1如果是靠上就是 HSSFCellStyle.VERTICAL_TOP;、
2.如果是居中就是 HSSFCellStyle.VERTICAL_CENTER;
3.如果是靠下就是 HSSFCellStyle.VERTICAL_BOTTOM;
4.如果是兩端對齊就是 HSSFCellStyle.VERTICAL_JUSTIFY;
2.3.2單元格邊框樣式
單元格的高和是可以設定的setHeightInPoints(int) 設定行高,setDefaultColumnWidth(int)設定列寬,邊框的顏色需要getindex不然會報錯的
Row row = sheet.createRow(1); // 建立一個行 第一行
row.setHeightInPoints(40);
/**
* 設施列寬
*/
sheet.setDefaultColumnWidth(40);
Cell cell = row.createCell(1);
cell.setCellValue(" 單元格邊框");
/**
* 單元格樣式類
*/
CellStyle cellstyle = wb.createCellStyle();
cellstyle.setBorderBottom(CellStyle.BORDER_DOTTED);// 底部邊框
/**
* IndexedColors顏色索引類 選取完顏色之後還要getIndex()
* 或者index都可以
*/
cellstyle.setBottomBorderColor(IndexedColors.BLUE.getIndex());// 設定底部邊框顏色
cellstyle.setBorderLeft(CellStyle.BORDER_THIN); // 左邊邊框
cellstyle.setLeftBorderColor(IndexedColors.GREEN.getIndex()); // 左邊邊框顏色
cellstyle.setBorderRight(CellStyle.BORDER_THIN); // 右邊邊框
cellstyle.setRightBorderColor(HSSFColor.RED.index);//