Java:用POI读写Excel
大家注意,請用最新的POI開發包進行操作,版本至少要不低于3.2,這樣才能順利完成以下所有操作。POI3.2下載地址是:http://apache.freelamp.com/poi/release/bin/poi-bin-3.2-FINAL-20081019.tar.gz
創建一個新的Workbook
?????HSSFWorkbook wb = new HSSFWorkbook();
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
?????fileOut.close();
創建一個新的 Sheet
?????HSSFWorkbook wb = new HSSFWorkbook();
?????HSSFSheet sheet1 = wb.createSheet("new sheet");
?????HSSFSheet sheet2 = wb.createSheet("second sheet");
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
?????fileOut.close();
創建單元格 Cells
?????HSSFWorkbook wb = new HSSFWorkbook();
?????HSSFSheet sheet = wb.createSheet("new sheet");
// 創建一個行row同時在上面設置一些單元格,注意,行是從0開始,這里創建第一行。
HSSFRow row = sheet.createRow((short)0);
?????// 創建單元格并為他設置一個值,注意,單元格也是從0開始
?????HSSFCell cell = row.createCell((short)0);
?????cell.setCellValue(1);
?????// 可以在同一行創建多個單元格.
?????row.createCell((short)1).setCellValue(1.2);
?????row.createCell((short)2).setCellValue("This is a string");
?????row.createCell((short)3).setCellValue(true);
?????// 將這些數據輸出為Excel
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
?????fileOut.close();
創建關于時間的單元格 Cells
?????HSSFWorkbook wb = new HSSFWorkbook();
?????HSSFSheet sheet = wb.createSheet("new sheet");
?????//創建一個行row同時在上面設置一些單元格,注意,行是從0開始,這里創建第一行
?????HSSFRow row = sheet.createRow((short)0);
?????// 創建一個單元格并為其設置時間值,第一個單元格是原始時間值Double類型,沒有格式
?????HSSFCell cell = row.createCell((short)0);
?????cell.setCellValue(new Date());
?????// 現在將第二個單元格格式化為日期+時間.
// 通過workbook創建一個新的單元格風格(cell style)是很重要的??
// 否則你在修改這個單元格的風格的時候可能會影響到其他單元格的風格。
HSSFCellStyle cellStyle = wb.createCellStyle();
?????cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
?????cell = row.createCell((short)1);
?????cell.setCellValue(new Date());
?????cell.setCellStyle(cellStyle);
?????// 寫出文件
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
?????fileOut.close();
操作不同類型的單元格
?????HSSFWorkbook wb = new HSSFWorkbook();
?????HSSFSheet sheet = wb.createSheet("new sheet");
?????HSSFRow row = sheet.createRow((short)2);
?????row.createCell((short) 0).setCellValue(1.1);
?????row.createCell((short) 1).setCellValue(new Date());
?????row.createCell((short) 2).setCellValue("a string");
?????row.createCell((short) 3).setCellValue(true);
?????row.createCell((short) 4).setCellType(HSSFCell.CELL_TYPE_ERROR);
?????// 寫出文件
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
fileOut.close();
//一點廢話:由此可見,在上面的關于日期的格式化我們不一定要通過poi來做,我們可以將數據都格式化好了以后,轉換成String類型來寫入Excel,這樣從一定程度上統一寫入單元格的代碼,實現代碼復用。
示范不同的隊列選項(也就是單元格內容居左、居右等等)
?????public static void main(String[] args)
?????????????throws IOException
?????{
?????????HSSFWorkbook wb = new HSSFWorkbook();
?????????HSSFSheet sheet = wb.createSheet("new sheet");
?????????HSSFRow row = sheet.createRow((short) 2);
?????????createCell(wb, row, (short) 0, HSSFCellStyle.ALIGN_CENTER);
?????????createCell(wb, row, (short) 1, HSSFCellStyle.ALIGN_CENTER_SELECTION);
?????????createCell(wb, row, (short) 2, HSSFCellStyle.ALIGN_FILL);
?????????createCell(wb, row, (short) 3, HSSFCellStyle.ALIGN_GENERAL);
?????????createCell(wb, row, (short) 4, HSSFCellStyle.ALIGN_JUSTIFY);
?????????createCell(wb, row, (short) 5, HSSFCellStyle.ALIGN_LEFT);
?????????createCell(wb, row, (short) 6, HSSFCellStyle.ALIGN_RIGHT);
?????????// 寫入文件
?????????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????????wb.write(fileOut);
?????????fileOut.close();
?????}
?????/**
??????* 創建一個單元格使其按照某種方式排列
??????*
??????* @param wb?????????the workbook
??????* @param row????????生成單元格的行
??????* @param column?????在這個行中單元格所處的列數
??????* @param align??????單元格內容的排列方式.
??????*/
?????private static void createCell(HSSFWorkbook wb, HSSFRow row, short column, short align)
?????{
?????????HSSFCell cell = row.createCell(column);
?????????cell.setCellValue("Align It");
?????????HSSFCellStyle cellStyle = wb.createCellStyle();
?????????cellStyle.setAlignment(align);
?????????cell.setCellStyle(cellStyle);
?????}
操作邊框
?????HSSFWorkbook wb = new HSSFWorkbook();
?????HSSFSheet sheet = wb.createSheet("new sheet");
?????// 創建一行(row)并為其設置單元格,行從0開始.
?????HSSFRow row = sheet.createRow((short) 1);
?????// 創建單元格并為其設置數值.
?????HSSFCell cell = row.createCell((short) 1);
?????cell.setCellValue(4);
?????// 在單元格周圍設置邊框.
?????HSSFCellStyle style = wb.createCellStyle();
?????style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
?????style.setBottomBorderColor(HSSFColor.BLACK.index);
?????style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
?????style.setLeftBorderColor(HSSFColor.GREEN.index);
?????style.setBorderRight(HSSFCellStyle.BORDER_THIN);
?????style.setRightBorderColor(HSSFColor.BLUE.index);
?????style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM_DASHED);
?????style.setTopBorderColor(HSSFColor.BLACK.index);
?????cell.setCellStyle(style);
?????// 寫入文件
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
?????fileOut.close();
迭代遍歷行及其單元格
有時,我們喜歡遍歷一個Sheet的所有行,或者一行的所有單元格,這時可以通過循環來遍歷還是比較簡單的。
幸運的是,我們這有個非常簡單的方法。HSSFRow定義了一個CellIterator的內部類來迭代遍歷所有的單元格(通過調用row.celIterator獲取),而且HSSFSheet也提供了一個rowIterator方法給出了遍歷所有行的迭代器。
(Unfortunately, due to the broken and backwards-incompatible way that Java 5 foreach loops were implemented, it isn't possible to use them on a codebase that supports Java 1.4, as POI does)
??????????HSSFSheet sheet = wb.getSheetAt(0);
??????????for (Iterator rit = sheet.rowIterator(); rit.hasNext(); ) {
??????????????????HSSFRow row = (HSSFRow)rit.next();
??????????????????for (Iterator cit = row.cellIterator(); cit.hasNext(); ) {
???????????????????????????HSSFCell cell = (HSSFCell)cit.next();
???????????????????????????// Do something here
??????????????????}
??????????}
??????????HSSFSheet sheet = wb.getSheetAt(0);
??????????for (Iterator<HSSFRow> rit = (Iterator<HSSFRow>)sheet.rowIterator(); rit.hasNext(); ) {
??????????????????HSSFRow row = rit.next();
??????????????????for (Iterator<HSSFCell> cit = (Iterator<HSSFCell>)row.cellIterator(); cit.hasNext(); ) {
???????????????????????????HSSFCell cell = cit.next();
???????????????????????????// Do something here
??????????????????}
??????????}
使用java5的特有的前端循環(foreach loops)遍歷行和單元格- OOXML Branch Only
有時候我們需要遍歷一個Sheet的所有行或者一行的所有列,這時如果使用java5或者更高版本的話,可以采用這種新的循環方式的處理。
幸運的是,這也非常簡單。HSSFSheet和HSSFRow都實現了java.lang.Iterator接口來允許新的循環方式的運行。 HSSFRow允許通過CellIterator內部類來處理單元格的循環,HSSFSheet給出了rowIterator方法來遍歷所有的行。
??????????HSSFSheet sheet = wb.getSheetAt(0);
??????????for (HSSFRow row : sheet.rowIterator()) {
??????????????????for (HSSFCell cell : row.cellIterator()) {
???????????????????????????// Do something here
??????????????????}
??????????}
內容提取
對于大多數的內容提取需求,標準ExcelExtractor類應該能滿足您所有的需求。
??????????InputStream inp = new FileInputStream("workbook.xls");
??????????HSSFWorkbook wb = new HSSFWorkbook(new POIFSFileSystem(inp));
??????????ExcelExtractor extractor = new ExcelExtractor(wb);
??????????extractor.setFormulasNotResults(true);
??????????extractor.setIncludeSheetNames(false);
??????????String text = extractor.getText();
填充和顏色
?????HSSFWorkbook wb = new HSSFWorkbook();
?????HSSFSheet sheet = wb.createSheet("new sheet");
?????// 創建一行,并為其設置單元格,行從0開始 .
?????HSSFRow row = sheet.createRow((short) 1);
?????// Aqua 背景色
?????HSSFCellStyle style = wb.createCellStyle();
?????style.setFillBackgroundColor(HSSFColor.AQUA.index);
?????style.setFillPattern(HSSFCellStyle.BIG_SPOTS);
?????HSSFCell cell = row.createCell((short) 1);
?????cell.setCellValue("X");
?????cell.setCellStyle(style);
?????// Orange "前景色".
?????style = wb.createCellStyle();
?????style.setFillForegroundColor(HSSFColor.ORANGE.index);
?????style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
?????cell = row.createCell((short) 2);
?????cell.setCellValue("X");
?????cell.setCellStyle(style);
?????// 寫入文件
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
?????fileOut.close();
合并單元格
?????HSSFWorkbook wb = new HSSFWorkbook();
?????HSSFSheet sheet = wb.createSheet("new sheet");
?????HSSFRow row = sheet.createRow((short) 1);
?????HSSFCell cell = row.createCell((short) 1);
?????cell.setCellValue("This is a test of merging");
?????sheet.addMergedRegion(new Region(1,(short)1,1,(short)2));
?????// 寫入文件
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
?????fileOut.close();
一點廢話:關于new Region(1,(short)1,1,(short)2):四個參數分別為起始行、起始列、終止行、終止列,如果要在合并的單元格中寫入數據,首先在起始行列的單元格中寫入內容,之后從起始行列處開始拉伸合并單元格到終止行列。
字體設置
?????HSSFWorkbook wb = new HSSFWorkbook();
?????HSSFSheet sheet = wb.createSheet("new sheet");
?????//創建行
?????HSSFRow row = sheet.createRow((short) 1);
?????// 創建一個系的呢字體并設置其屬性.
?????HSSFFont font = wb.createFont();
?????font.setFontHeightInPoints((short)24);
?????font.setFontName("Courier New");
?????font.setItalic(true);
?????font.setStrikeout(true);
?????// 字體設置給一個HSSFCellStyle對象.
?????HSSFCellStyle style = wb.createCellStyle();
?????style.setFont(font);
?????// 創建一個單元格并為其設置值
?????HSSFCell cell = row.createCell((short) 1);
?????cell.setCellValue("This is a test of fonts");
?????cell.setCellStyle(style);
?????//寫入文件
?????FileOutputStream fileOut = new FileOutputStream("c://workbook.xls");
?????wb.write(fileOut);
?????fileOut.close();
注意:一個workbook中字體數目被限制在32767個以內。你應該在程序中重用字體來代替為每個單元格創建新字體
下面寫法是錯誤的:
?????????for (int i = 0; i < 10000; i++) {
?????????????HSSFRow row = sheet.createRow(i);
?????????????HSSFCell cell = row.createCell((short) 0);
?????????????HSSFCellStyle style = workbook.createCellStyle();
?????????????HSSFFont font = workbook.createFont();
?????????????font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
?????????????style.setFont(font);
?????????????cell.setCellStyle(style);
?????????}
修正后:
?????????HSSFCellStyle style = workbook.createCellStyle();
?????????HSSFFont font = workbook.createFont();
?????????font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
?????????style.setFont(font);
?????????for (int i = 0; i < 10000; i++) {
?????????????HSSFRow row = sheet.createRow(i);
?????????????HSSFCell cell = row.createCell((short) 0);
?????????????cell.setCellStyle(style);
?????????}
一點廢話:將創建字體的代碼移出循環體。
如何讀取超鏈接
?????HSSFSheet sheet = workbook.getSheetAt(0);
?????HSSFCell cell = sheet.getRow(0).getCell((short)0);
?????HSSFHyperlink link = cell.getHyperlink();
?????if(link != null){
?????????System.out.println(link.getAddress());
?????}
如何設置超鏈接
?????HSSFWorkbook wb = new HSSFWorkbook();
?????//超鏈接的單元格風格
?????//超鏈接默認的是藍色底邊框
?????HSSFCellStyle hlink_style = wb.createCellStyle();
?????HSSFFont hlink_font = wb.createFont();
?????hlink_font.setUnderline(HSSFFont.U_SINGLE);
?????hlink_font.setColor(HSSFColor.BLUE.index);
?????hlink_style.setFont(hlink_font);
?????HSSFCell cell;
?????HSSFSheet sheet = wb.createSheet("Hyperlinks");
?????//URL
?????cell = sheet.createRow(0).createCell((short)0);
?????cell.setCellValue("URL Link");
?????HSSFHyperlink link = new HSSFHyperlink(HSSFHyperlink.LINK_URL);
?????link.setAddress("http://poi.apache.org/");
?????cell.setHyperlink(link);
?????cell.setCellStyle(hlink_style);
?????//鏈接到當前路徑的一個文件
?????cell = sheet.createRow(1).createCell((short)0);
?????cell.setCellValue("File Link");
?????link = new HSSFHyperlink(HSSFHyperlink.LINK_FILE);
?????link.setAddress("link1.xls");
?????cell.setHyperlink(link);
?????cell.setCellStyle(hlink_style);
?????//鏈接到e-mail
?????cell = sheet.createRow(2).createCell((short)0);
?????cell.setCellValue("Email Link");
?????link = new HSSFHyperlink(HSSFHyperlink.LINK_EMAIL);
?????//note, if subject contains white spaces, make sure they are url-encoded
?????link.setAddress("");
?????cell.setHyperlink(link);
?????cell.setCellStyle(hlink_style);
?????//鏈接到 workbook的某個地方
?????//創建一個目標Sheet和單元格
?????HSSFSheet sheet2 = wb.createSheet("Target Sheet");
?????sheet2.createRow(0).createCell((short)0).setCellValue("Target Cell");
?????cell = sheet.createRow(3).createCell((short)0);
?????cell.setCellValue("Worksheet Link");
?????link = new HSSFHyperlink(HSSFHyperlink.LINK_DOCUMENT);
?????link.setAddress("'Target Sheet'!A1");
?????cell.setHyperlink(link);
?????cell.setCellStyle(hlink_style);
?????FileOutputStream out = new FileOutputStream("c://hssf-links.xls");
?????wb.write(out);
?????out.close();
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的Java:用POI读写Excel的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IT人分类,你属于哪个级别?
- 下一篇: 程序员应该知道的二十三种设计模式