设为首页 收藏本站
查看: 843|回复: 0

[经验分享] 使用Apache POI API读写Excel

[复制链接]

尚未签到

发表于 2015-11-14 09:32:30 | 显示全部楼层 |阅读模式
目录(?)[-]


  • 读取Excel文件
  • 写入Excel文件
  • 读取Excel公式
  • 写入Excel公式
  原文地址:http://www.journaldev.com/2562/java-readwrite-excel-file-using-apache-poi-api.
  

  有时候我们需要从Excel文件中读取数据,或者我们为了商务或者财政的目的生成Excel格式的报表.Java没有对操作Excel文件提供内在的支持,所以我们需要寻找开源的APIs.当我开始寻找操作Excel的APIs时候,大部分人建议使用JExcel或者Apache POI.

在深入研究后,我发现由于以下主要原因Apache POI是正确的选择.还有些关于高级特性的原因,但是我们不深入太多细节.
1)Apache基金的支持.
2)JExcel不支持xlsx格式而POI既支持xls格式又支持xlsx格式.
3)Apache POI是基于流的处理,因此更适合大文件和要求更少的内存.
Apache POI对处理Excel文件提供了强大的支持,并且能处理xls和xlsx格式的电子表格.


关于Apache POI一些重要的地方:
1)Apache POI包含适合Excel97-2007(.xls文件)的HSSF实现.
2)Apache POI XSSF实现用来处理Excel2007文件(.xlsx).
3)Apache POI HSSF和XSSF提供了读/写/修改Excel表格的机制.
4)Apache POI提供了XSSF的一个扩展SXSSF用来处理非常大的Excel工作单元.SXSSF API需要更少的内存,因此当处理非常大的电子表格同时堆内存又有限时,很合适使用.
5)有两种模式可供选择--事件模式和用户模式.事件模式要求更少的内存,因为用tokens来读取Excel并处理.用户模式更加面向对象并且容易使用,因此在我们的示例中使用用户   模式.
6)Apache POI为额外的Excel特性提供了强大支持,例如处理公式,创建单元格样式--颜色,边框,字体,头部,脚部,数据验证,图像,超链接等.

Apache POI的Maven依赖

[java] viewplaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/ico_fork.svg

  • <span style=&quot;font-size:14px;&quot;><dependency>  
  •     <groupId>org.apache.poi</groupId>  
  •     <artifactId>poi</artifactId>  
  •     <version>3.10-FINAL</version>  
  • </dependency>  
  • <dependency>  
  •     <groupId>org.apache.poi</groupId>  
  •     <artifactId>poi-ooxml</artifactId>  
  •     <version>3.10-FINAL</version>  
  • </dependency></span>  



Apache POI的当前版本是3.10-FINAL.如果你使用单独的java应用,添加jars根据下面的图片.
http://cdn1.journaldev.com/wp-content/uploads/2014/03/Apache-POI-Dependencies.png

读取Excel文件
假设我们有一个叫Sample.xlsx的Excel文件,里面有两个sheet并且下面图片中的数据.我们想要读取这个Excel文件并且创建Countries list.sheet1有些额外的数据,当我们解析时会忽略它.
  
http://1-ps.googleusercontent.com/x/www.journaldev.com/cdn2.journaldev.com/wp-content/uploads/2014/03/450x366xJava-Read-Excel-File-1-450x366.png.pagespeed.ic.GtvRSYybva.png

http://1-ps.googleusercontent.com/x/www.journaldev.com/cdn1.journaldev.com/wp-content/uploads/2014/03/450x366xJava-Read-Excel-File-2-450x366.png.pagespeed.ic.GVs2b-4eT8.png

  我们的国家(Country)java bean如下:

  Country.java

  
[java] viewplaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/ico_fork.svg

  • package com.journaldev.excel.read;  
  •    
  • public class Country {  
  •    
  •     private String name;  
  •     private String shortCode;  
  •       
  •     public Country(String n, String c){  
  •         this.name=n;  
  •         this.shortCode=c;  
  •     }  
  •       
  •     public String getName() {  
  •         return name;  
  •     }  
  •     public void setName(String name) {  
  •         this.name = name;  
  •     }  
  •     public String getShortCode() {  
  •         return shortCode;  
  •     }  
  •     public void setShortCode(String shortCode) {  
  •         this.shortCode = shortCode;  
  •     }  
  •       
  •     @Override  
  •     public String toString(){  
  •         return name &#43; &quot;::&quot; &#43; shortCode;  
  •     }  
  •       
  • }  

读取Excel文件并创建Countries list代码如下:
  
  ReadExcelFileToList.java

  
[java] viewplaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/ico_fork.svg

  • package com.journaldev.excel.read;  
  •    
  • import java.io.FileInputStream;  
  • import java.io.IOException;  
  • import java.util.ArrayList;  
  • import java.util.Iterator;  
  • import java.util.List;  
  •    
  • import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
  • import org.apache.poi.ss.usermodel.Cell;  
  • import org.apache.poi.ss.usermodel.Row;  
  • import org.apache.poi.ss.usermodel.Sheet;  
  • import org.apache.poi.ss.usermodel.Workbook;  
  • import org.apache.poi.xssf.usermodel.XSSFWorkbook;  
  •    
  • public class ReadExcelFileToList {  
  •    
  •     public static List<Country> readExcelData(String fileName) {  
  •         List<Country> countriesList = new ArrayList<Country>();  
  •            
  •         try {  
  •             //Create the input stream from the xlsx/xls file  
  •             FileInputStream fis = new FileInputStream(fileName);  
  •                
  •             //Create Workbook instance for xlsx/xls file input stream  
  •             Workbook workbook = null;  
  •             if(fileName.toLowerCase().endsWith(&quot;xlsx&quot;)){  
  •                 workbook = new XSSFWorkbook(fis);  
  •             }else if(fileName.toLowerCase().endsWith(&quot;xls&quot;)){  
  •                 workbook = new HSSFWorkbook(fis);  
  •             }  
  •                
  •             //Get the number of sheets in the xlsx file  
  •             int numberOfSheets = workbook.getNumberOfSheets();  
  •                
  •             //loop through each of the sheets  
  •             for(int i=0; i < numberOfSheets; i&#43;&#43;){  
  •                   
  •                 //Get the nth sheet from the workbook  
  •                 Sheet sheet = workbook.getSheetAt(i);  
  •                   
  •                 //every sheet has rows, iterate over them  
  •                 Iterator<Row> rowIterator = sheet.iterator();  
  •                 while (rowIterator.hasNext())   
  •                 {  
  •                     String name = &quot;&quot;;  
  •                     String shortCode = &quot;&quot;;  
  •                        
  •                     //Get the row object  
  •                     Row row = rowIterator.next();  
  •                        
  •                     //Every row has columns, get the column iterator and iterate over them  
  •                     Iterator<Cell> cellIterator = row.cellIterator();  
  •                         
  •                     while (cellIterator.hasNext())   
  •                     {  
  •                         //Get the Cell object  
  •                         Cell cell = cellIterator.next();  
  •                            
  •                         //check the cell type and process accordingly  
  •                         switch(cell.getCellType()){  
  •                         case Cell.CELL_TYPE_STRING:  
  •                             if(shortCode.equalsIgnoreCase(&quot;&quot;)){  
  •                                 shortCode = cell.getStringCellValue().trim();  
  •                             }else if(name.equalsIgnoreCase(&quot;&quot;)){  
  •                                 //2nd column  
  •                                 name = cell.getStringCellValue().trim();  
  •                             }else{  
  •                                 //random data, leave it  
  •                                 System.out.println(&quot;Random data::&quot;&#43;cell.getStringCellValue());  
  •                             }  
  •                             break;  
  •                         case Cell.CELL_TYPE_NUMERIC:  
  •                             System.out.println(&quot;Random data::&quot;&#43;cell.getNumericCellValue());  
  •                         }  
  •                     } //end of cell iterator  
  •                     Country c = new Country(name, shortCode);  
  •                     countriesList.add(c);  
  •                 } //end of rows iterator  
  •                   
  •                   
  •             } //end of sheets for loop  
  •                
  •             //close file input stream  
  •             fis.close();  
  •                
  •         } catch (IOException e) {  
  •             e.printStackTrace();  
  •         }  
  •            
  •         return countriesList;  
  •     }  
  •    
  •     public static void main(String args[]){  
  •         List<Country> list = readExcelData(&quot;Sample.xlsx&quot;);  
  •         System.out.println(&quot;Country List\n&quot;&#43;list);  
  •     }  
  •    
  • }  

这个程序很容易明白,主要步骤如下:
1)根据文件类型(.xls与.xlsx)创建Workbook实例,xlsx用XSSFWorkbook,xls用HSSFWorkbook.我们可以基于文件名字使用工  厂模式创建一个包装类来创建Workbook实例.
2)使用Workbook getNumberOfSheets()来获取sheet的数量,然后循环解析每一个sheet.使用getSheetAt(int i)方法获取             Sheet实例.
3)获取Row和Cell迭代器来获取每一个Cell对象.Apache POI在这里使用了迭代器模式.
4)使用switch-case根据Cell的类型来处理它.
  
  现在我们运行上面的程序,在控制台产生如下的输出:

  
[java] viewplaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/ico_fork.svg

  • Random data::1.0  
  • Random data::2.0  
  • Random data::3.0  
  • Random data::4.0  
  • Country List  
  • [India::IND, Afghanistan::AFG, United States of America::USA, Anguilla::AIA,   
  • Denmark ::DNK, Dominican Republic ::DOM, Algeria ::DZA, Ecuador ::ECU]  

写入Excel文件
除了我们首先创建Workbook,然后设置sheets,rows,cells的&#20540;并且使用FileOutputStream把Workbook写入文件外,与读取Excel的操作相&#20284;.我们把从上面的方法读取countries list写入到另一个文件作一个例子:
  
  WriteListToExcelFile.java

  
[java] viewplaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/ico_fork.svg

  • package com.journaldev.excel.read;  
  •    
  • import java.io.FileOutputStream;  
  • import java.util.Iterator;  
  • import java.util.List;  
  •    
  • import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
  • import org.apache.poi.ss.usermodel.Cell;  
  • import org.apache.poi.ss.usermodel.Row;  
  • import org.apache.poi.ss.usermodel.Sheet;  
  • import org.apache.poi.ss.usermodel.Workbook;  
  • import org.apache.poi.xssf.usermodel.XSSFWorkbook;  
  •    
  • public class WriteListToExcelFile {  
  •    
  •     public static void writeCountryListToFile(String fileName, List<Country> countryList) throws Exception{  
  •         Workbook workbook = null;  
  •            
  •         if(fileName.endsWith(&quot;xlsx&quot;)){  
  •             workbook = new XSSFWorkbook();  
  •         }else if(fileName.endsWith(&quot;xls&quot;)){  
  •             workbook = new HSSFWorkbook();  
  •         }else{  
  •             throw new Exception(&quot;invalid file name, should be xls or xlsx&quot;);  
  •         }  
  •            
  •         Sheet sheet = workbook.createSheet(&quot;Countries&quot;);  
  •            
  •         Iterator<Country> iterator = countryList.iterator();  
  •            
  •         int rowIndex = 0;  
  •         while(iterator.hasNext()){  
  •             Country country = iterator.next();  
  •             Row row = sheet.createRow(rowIndex&#43;&#43;);  
  •             Cell cell0 = row.createCell(0);  
  •             cell0.setCellValue(country.getName());  
  •             Cell cell1 = row.createCell(1);  
  •             cell1.setCellValue(country.getShortCode());  
  •         }  
  •            
  •         //lets write the excel data to file now  
  •         FileOutputStream fos = new FileOutputStream(fileName);  
  •         workbook.write(fos);  
  •         fos.close();  
  •         System.out.println(fileName &#43; &quot; written successfully&quot;);  
  •     }  
  •       
  •     public static void main(String args[]) throws Exception{  
  •         List<Country> list = ReadExcelFileToList.readExcelData(&quot;Sample.xlsx&quot;);  
  •         WriteListToExcelFile.writeCountryListToFile(&quot;Countries.xls&quot;, list);  
  •     }  
  • }  

当我们执行上面的程序后,这个Excel文件被创建了,如下图:
  
  http://cdn.journaldev.com/wp-content/uploads/2014/03/Java-Write-Excel-File-450x397.png

  

  
读取Excel公式
有时候我们需要出来带有公司的复杂Excel文件.让我们来看一个关于读取一个有&#20540;的cell中的公式的例子:
  
  ReadExcelFormula.java

  
[java] viewplaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/ico_fork.svg

  • package com.journaldev.excel.read;  
  •    
  • import java.io.FileInputStream;  
  • import java.io.IOException;  
  • import java.util.Iterator;  
  •    
  • import org.apache.poi.ss.usermodel.Cell;  
  • import org.apache.poi.ss.usermodel.Row;  
  • import org.apache.poi.ss.usermodel.Sheet;  
  • import org.apache.poi.ss.usermodel.Workbook;  
  • import org.apache.poi.xssf.usermodel.XSSFWorkbook;  
  •    
  • public class ReadExcelFormula {  
  •    
  •     public static void readExcelFormula(String fileName) throws IOException{  
  •            
  •         FileInputStream fis = new FileInputStream(fileName);  
  •            
  •         //assuming xlsx file  
  •         Workbook workbook = new XSSFWorkbook(fis);  
  •         Sheet sheet = workbook.getSheetAt(0);  
  •         Iterator<Row> rowIterator = sheet.iterator();  
  •         while (rowIterator.hasNext())   
  •         {  
  •             Row row = rowIterator.next();  
  •             Iterator<Cell> cellIterator = row.cellIterator();  
  •                
  •             while (cellIterator.hasNext())   
  •             {  
  •                 Cell cell = cellIterator.next();  
  •                 switch(cell.getCellType()){  
  •                 case Cell.CELL_TYPE_NUMERIC:  
  •                     System.out.println(cell.getNumericCellValue());  
  •                     break;  
  •                 case Cell.CELL_TYPE_FORMULA:  
  •                     System.out.println(&quot;Cell Formula=&quot;&#43;cell.getCellFormula());  
  •                     System.out.println(&quot;Cell Formula Result Type=&quot;&#43;cell.getCachedFormulaResultType());  
  •                     if(cell.getCachedFormulaResultType() == Cell.CELL_TYPE_NUMERIC){  
  •                         System.out.println(&quot;Formula Value=&quot;&#43;cell.getNumericCellValue());  
  •                     }  
  •                 }  
  •             }  
  •         }  
  •     }  
  •       
  •     public static void main(String args[]) throws IOException {  
  •         readExcelFormula(&quot;FormulaMultiply.xlsx&quot;);  
  •     }  
  • }  

当我们执行上面的程序后,我们得到下面的输出:
  
  
[java] viewplaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/ico_fork.svg

  • 1.0  
  • 2.0  
  • 3.0  
  • 4.0  
  • Cell Formula=A1*A2*A3*A4  
  • Cell Formula Result Type=0  
  • Formula Value=24.0  

写入Excel公式
有时候,我们需要做一些计算然后把&#20540;写入cell.我们可以使用Excel公司来做这些计算,这样会更加精确,因为这些&#20540;会随着计算的&#20540;改变而改变.让我们来看一个关于写入一个带有公式的Excel的例子:
  
  WriteExcelWithFormula.java

  
[java] viewplaincopyprint?http://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/CODE_ico.pnghttp://onexin.iyunv.com/source/plugin/onexin_bigdata/https://code.iyunv.com/assets/ico_fork.svg

  • package com.journaldev.excel.read;  
  •    
  • import java.io.FileOutputStream;  
  • import java.io.IOException;  
  •    
  • import org.apache.poi.ss.usermodel.Row;  
  • import org.apache.poi.ss.usermodel.Sheet;  
  • import org.apache.poi.ss.usermodel.Workbook;  
  • import org.apache.poi.xssf.usermodel.XSSFWorkbook;  
  •    
  • public class WriteExcelWithFormula {  
  •    
  •     public static void writeExcelWithFormula(String fileName) throws IOException{  
  •         Workbook workbook = new XSSFWorkbook();  
  •         Sheet sheet = workbook.createSheet(&quot;Numbers&quot;);  
  •         Row row = sheet.createRow(0);  
  •         row.createCell(0).setCellValue(10);  
  •         row.createCell(1).setCellValue(20);  
  •         row.createCell(2).setCellValue(30);  
  •         //set formula cell  
  •         row.createCell(3).setCellFormula(&quot;A1*B1*C1&quot;);  
  •            
  •         //lets write to file  
  •         FileOutputStream fos = new FileOutputStream(fileName);  
  •         workbook.write(fos);  
  •         fos.close();  
  •         System.out.println(fileName &#43; &quot; written successfully&quot;);  
  •     }  
  •       
  •     public static void main(String[] args) throws IOException {  
  •         writeExcelWithFormula(&quot;Formulas.xlsx&quot;);  
  •     }  
  • }  

当我们执行上面的程序后,Excel被创建了,如下图:
  
  http://cdn.journaldev.com/wp-content/uploads/2014/03/java-write-excel-formula-450x343.png

  这就是所有Apache POI处理Excel文件的内容.查看POI源代码可以学习它的更多特性.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-139024-1-1.html 上篇帖子: Apache+PHP+MySQL服务器组合套件 下篇帖子: Windows系统下Apache性能优化,提高并发
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表