使用POI读取excel文件内容

来源:互联网 发布:图片归类整理软件 编辑:程序博客网 时间:2024/05/18 01:08

1.前言

项目中要求读取excel文件内容,并将其转化为xml格式。常见读取excel文档一般使用POI和JExcelAPI这两个工具。这里我们介绍使用POI实现读取excel文档。(Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能)

2.代码实例:

[java] view plain copy
  1. package com.zhongxin.web.ops.ad.util;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.text.SimpleDateFormat;  
  8. import java.util.Date;  
  9. import java.util.HashMap;  
  10. import java.util.Map;  
  11.   
  12. import org.apache.poi.hssf.usermodel.HSSFCell;  
  13. import org.apache.poi.hssf.usermodel.HSSFDateUtil;  
  14. import org.apache.poi.hssf.usermodel.HSSFRow;  
  15. import org.apache.poi.hssf.usermodel.HSSFSheet;  
  16. import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
  17. import org.apache.poi.poifs.filesystem.POIFSFileSystem;  
  18.   
  19. /** 
  20.  * 操作Excel表格的功能类 
  21.  */  
  22. public class ExcelReader {  
  23.     private POIFSFileSystem fs;  
  24.     private HSSFWorkbook wb;  
  25.     private HSSFSheet sheet;  
  26.     private HSSFRow row;  
  27.   
  28.     /** 
  29.      * 读取Excel表格表头的内容 
  30.      * @param InputStream 
  31.      * @return String 表头内容的数组 
  32.      */  
  33.     public String[] readExcelTitle(InputStream is) {  
  34.         try {  
  35.             fs = new POIFSFileSystem(is);  
  36.             wb = new HSSFWorkbook(fs);  
  37.         } catch (IOException e) {  
  38.             e.printStackTrace();  
  39.         }  
  40.         sheet = wb.getSheetAt(0);  
  41.         row = sheet.getRow(0);  
  42.         // 标题总列数  
  43.         int colNum = row.getPhysicalNumberOfCells();  
  44.         System.out.println("colNum:" + colNum);  
  45.         String[] title = new String[colNum];  
  46.         for (int i = 0; i < colNum; i++) {  
  47.             //title[i] = getStringCellValue(row.getCell((short) i));  
  48.             title[i] = getCellFormatValue(row.getCell((short) i));  
  49.         }  
  50.         return title;  
  51.     }  
  52.   
  53.     /** 
  54.      * 读取Excel数据内容 
  55.      * @param InputStream 
  56.      * @return Map 包含单元格数据内容的Map对象 
  57.      */  
  58.     public Map<Integer, String> readExcelContent(InputStream is) {  
  59.         Map<Integer, String> content = new HashMap<Integer, String>();  
  60.         String str = "";  
  61.         try {  
  62.             fs = new POIFSFileSystem(is);  
  63.             wb = new HSSFWorkbook(fs);  
  64.         } catch (IOException e) {  
  65.             e.printStackTrace();  
  66.         }  
  67.         sheet = wb.getSheetAt(0);  
  68.         // 得到总行数  
  69.         int rowNum = sheet.getLastRowNum();  
  70.         row = sheet.getRow(0);  
  71.         int colNum = row.getPhysicalNumberOfCells();  
  72.         // 正文内容应该从第二行开始,第一行为表头的标题  
  73.         for (int i = 1; i <= rowNum; i++) {  
  74.             row = sheet.getRow(i);  
  75.             int j = 0;  
  76.             while (j < colNum) {  
  77.                 // 每个单元格的数据内容用"-"分割开,以后需要时用String类的replace()方法还原数据  
  78.                 // 也可以将每个单元格的数据设置到一个javabean的属性中,此时需要新建一个javabean  
  79.                 // str += getStringCellValue(row.getCell((short) j)).trim() +  
  80.                 // "-";  
  81.                 str += getCellFormatValue(row.getCell((short) j)).trim() + "    ";  
  82.                 j++;  
  83.             }  
  84.             content.put(i, str);  
  85.             str = "";  
  86.         }  
  87.         return content;  
  88.     }  
  89.   
  90.     /** 
  91.      * 获取单元格数据内容为字符串类型的数据 
  92.      *  
  93.      * @param cell Excel单元格 
  94.      * @return String 单元格数据内容 
  95.      */  
  96.     private String getStringCellValue(HSSFCell cell) {  
  97.         String strCell = "";  
  98.         switch (cell.getCellType()) {  
  99.         case HSSFCell.CELL_TYPE_STRING:  
  100.             strCell = cell.getStringCellValue();  
  101.             break;  
  102.         case HSSFCell.CELL_TYPE_NUMERIC:  
  103.             strCell = String.valueOf(cell.getNumericCellValue());  
  104.             break;  
  105.         case HSSFCell.CELL_TYPE_BOOLEAN:  
  106.             strCell = String.valueOf(cell.getBooleanCellValue());  
  107.             break;  
  108.         case HSSFCell.CELL_TYPE_BLANK:  
  109.             strCell = "";  
  110.             break;  
  111.         default:  
  112.             strCell = "";  
  113.             break;  
  114.         }  
  115.         if (strCell.equals("") || strCell == null) {  
  116.             return "";  
  117.         }  
  118.         if (cell == null) {  
  119.             return "";  
  120.         }  
  121.         return strCell;  
  122.     }  
  123.   
  124.     /** 
  125.      * 获取单元格数据内容为日期类型的数据 
  126.      *  
  127.      * @param cell 
  128.      *            Excel单元格 
  129.      * @return String 单元格数据内容 
  130.      */  
  131.     private String getDateCellValue(HSSFCell cell) {  
  132.         String result = "";  
  133.         try {  
  134.             int cellType = cell.getCellType();  
  135.             if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {  
  136.                 Date date = cell.getDateCellValue();  
  137.                 result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1)  
  138.                         + "-" + date.getDate();  
  139.             } else if (cellType == HSSFCell.CELL_TYPE_STRING) {  
  140.                 String date = getStringCellValue(cell);  
  141.                 result = date.replaceAll("[年月]""-").replace("日""").trim();  
  142.             } else if (cellType == HSSFCell.CELL_TYPE_BLANK) {  
  143.                 result = "";  
  144.             }  
  145.         } catch (Exception e) {  
  146.             System.out.println("日期格式不正确!");  
  147.             e.printStackTrace();  
  148.         }  
  149.         return result;  
  150.     }  
  151.   
  152.     /** 
  153.      * 根据HSSFCell类型设置数据 
  154.      * @param cell 
  155.      * @return 
  156.      */  
  157.     private String getCellFormatValue(HSSFCell cell) {  
  158.         String cellvalue = "";  
  159.         if (cell != null) {  
  160.             // 判断当前Cell的Type  
  161.             switch (cell.getCellType()) {  
  162.             // 如果当前Cell的Type为NUMERIC  
  163.             case HSSFCell.CELL_TYPE_NUMERIC:  
  164.             case HSSFCell.CELL_TYPE_FORMULA: {  
  165.                 // 判断当前的cell是否为Date  
  166.                 if (HSSFDateUtil.isCellDateFormatted(cell)) {  
  167.                     // 如果是Date类型则,转化为Data格式  
  168.                       
  169.                     //方法1:这样子的data格式是带时分秒的:2011-10-12 0:00:00  
  170.                     //cellvalue = cell.getDateCellValue().toLocaleString();  
  171.                       
  172.                     //方法2:这样子的data格式是不带带时分秒的:2011-10-12  
  173.                     Date date = cell.getDateCellValue();  
  174.                     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
  175.                     cellvalue = sdf.format(date);  
  176.                       
  177.                 }  
  178.                 // 如果是纯数字  
  179.                 else {  
  180.                     // 取得当前Cell的数值  
  181.                     cellvalue = String.valueOf(cell.getNumericCellValue());  
  182.                 }  
  183.                 break;  
  184.             }  
  185.             // 如果当前Cell的Type为STRIN  
  186.             case HSSFCell.CELL_TYPE_STRING:  
  187.                 // 取得当前的Cell字符串  
  188.                 cellvalue = cell.getRichStringCellValue().getString();  
  189.                 break;  
  190.             // 默认的Cell值  
  191.             default:  
  192.                 cellvalue = " ";  
  193.             }  
  194.         } else {  
  195.             cellvalue = "";  
  196.         }  
  197.         return cellvalue;  
  198.   
  199.     }  
  200.   
  201.     public static void main(String[] args) {  
  202.         try {  
  203.             // 对读取Excel表格标题测试  
  204.             InputStream is = new FileInputStream("d:\\test2.xls");  
  205.             ExcelReader excelReader = new ExcelReader();  
  206.             String[] title = excelReader.readExcelTitle(is);  
  207.             System.out.println("获得Excel表格的标题:");  
  208.             for (String s : title) {  
  209.                 System.out.print(s + " ");  
  210.             }  
  211.   
  212.             // 对读取Excel表格内容测试  
  213.             InputStream is2 = new FileInputStream("d:\\test2.xls");  
  214.             Map<Integer, String> map = excelReader.readExcelContent(is2);  
  215.             System.out.println("获得Excel表格的内容:");  
  216.             for (int i = 1; i <= map.size(); i++) {  
  217.                 System.out.println(map.get(i));  
  218.             }  
  219.   
  220.         } catch (FileNotFoundException e) {  
  221.             System.out.println("未找到指定路径的文件!");  
  222.             e.printStackTrace();  
  223.         }  
  224.     }  
  225. }  

3.总结

因为excel单元格中的内容往往都有一定的格式,比如日期型,数字型,字符串型,因此在读取的时候要进行格式判断,不然会出现错误。常见的就是不能正常读取日期。在代码实例中有一个方法:

getCellFormatValue(HSSFCell cell)

往这个方法中传入excel单元格就能识别单元格格式,并转化为正确的格式。


Reference:

[1] shasiqq, 使用POI读取excel文件内容, http://blog.csdn.net/shasiqq/article/details/51131902

原创粉丝点击