当前位置:   article > 正文

Java使用poi 5.0解析Excel工作簿的例子_poi5.0

poi5.0

目录

写在之前

一、需求

二、思路

三、实现

1.Excel实体类ExcelBean

2.工具类ExcelParser

 3.测试类Test 

4.工具类功能描述

5.效果

表格数据

 运行结果

依赖的Jar包


写在之前

Excel文档是日常办公中非常普遍的一种数据记录模式。在业务场景中,往往有“导入Excel到某某系统中”的需求,所以这里记录一种使用poi 5.0系列的jar包解析为Java实体类的方法。

由于对Excel工作簿的理解有限,写代码水平有限;本例子更多的是经验记录和练习,参考意义因人而异。有不妥之处,还请批评指正。

一、需求

根据指定的Sheet顺序号,从每个Sheet指定的行以下,读取Excel工作簿数据为包含常用数据对象的实体类对象。

二、思路

结合poi的org.apache.poi.ss.usermodel.WorkBook接口,先将Excel工作簿抽象为工作表、标题、数据行。通过HSSFWorkbookXSSFWorkbook实现类的方法,将Sheet顺序号和指定的行号作为可配置的参数,获取有关对象后转换为实体类。

三、实现

1.Excel实体类ExcelBean

  1. package com.myself.pottest;
  2. import java.util.List;
  3. import java.util.Map;
  4. /**
  5. * 描述一个Excel工作簿其中的一个工作表的实体类
  6. */
  7. public class ExcelBean {
  8. /*
  9. 工作表名
  10. */
  11. private String sheetname = null;
  12. /*
  13. 表格标题
  14. */
  15. private Map<Integer, Object> columntitle = null;
  16. /*
  17. 表格主体部分
  18. */
  19. private List<Map<Integer, Object>> rows = null;
  20. public ExcelBean() {
  21. }
  22. public ExcelBean(String sheetname, Map<Integer, Object> columntitle, List<Map<Integer, Object>> row) {
  23. this.sheetname = sheetname;
  24. this.columntitle = columntitle;
  25. this.rows = row;
  26. }
  27. public String getSheetname() {
  28. return sheetname;
  29. }
  30. public void setSheetname(String sheetname) {
  31. this.sheetname = sheetname;
  32. }
  33. public Map<Integer, Object> getColumntitle() {
  34. return columntitle;
  35. }
  36. public void setColumntitle(Map<Integer, Object> columntitle) {
  37. this.columntitle = columntitle;
  38. }
  39. public List<Map<Integer, Object>> getRows() {
  40. return rows;
  41. }
  42. public void setRows(List<Map<Integer, Object>> rows) {
  43. this.rows = rows;
  44. }
  45. @Override
  46. public String toString() {
  47. return "ExcelBean{" +
  48. "sheetname='" + sheetname + '\'' +
  49. ", columntitle=" + columntitle +
  50. ", rows=" + rows +
  51. '}';
  52. }
  53. }

2.工具类ExcelParser

 

  1. package com.myself.pottest;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileNotFoundException;
  5. import java.io.IOException;
  6. import java.util.*;
  7. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  8. import org.apache.poi.ss.usermodel.Cell;
  9. import org.apache.poi.ss.usermodel.Row;
  10. import org.apache.poi.ss.usermodel.Sheet;
  11. import org.apache.poi.ss.usermodel.Workbook;
  12. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  13. public class ExcelParser {
  14. /**
  15. *Excel文件
  16. */
  17. private File file;
  18. /**
  19. * Workbook接口,用于根据条件实例化不同的实现类
  20. */
  21. private Workbook ExcelWorkbook = null;
  22. public ExcelParser(String filepath ) {
  23. this.file = new File(filepath);
  24. }
  25. /**
  26. * 读取文件,判断文件类型并创建有关实现类来实现Workbook接口。
  27. */
  28. public void Read() {
  29. try (FileInputStream fis = new FileInputStream(file)) {
  30. if (file.getName().endsWith(".xls")) {
  31. ExcelWorkbook = new HSSFWorkbook(fis);
  32. } else if (file.getName().endsWith(".xlsx")) {
  33. ExcelWorkbook = new XSSFWorkbook(fis);
  34. } else {
  35. System.out.println(file.getName()+"不是可以被本类解析的文件");
  36. return;
  37. }
  38. } catch (FileNotFoundException e) {
  39. System.out.println("文件不存在!");
  40. e.printStackTrace();
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. /**
  46. * 获取Workbook实现类的指定位置的Sheet实现类信息到Map中,并返回。
  47. * @param SheetNum Map<Integer,Integer>,存放需要读取的Excel的Sheet的顺序号及其指定行号,如第一个Sheet就写1,第一行就写1
  48. * @return
  49. */
  50. private Map<Integer, Object> GetSheet2Map(Map<Integer,Integer> SheetNum) {
  51. Map<Integer, Object> SheetMap = new LinkedHashMap<>();
  52. if (SheetNum == null){
  53. for (int k = 0; k < ExcelWorkbook.getNumberOfSheets(); k++) {
  54. Sheet sheet = ExcelWorkbook.getSheetAt(k);
  55. SheetMap.put((k + 1), sheet.getSheetName());
  56. }
  57. }else if(SheetNum != null){
  58. for (Map.Entry<Integer,Integer> entry:SheetNum.entrySet()) {
  59. Sheet sheet = ExcelWorkbook.getSheetAt(entry.getKey()-1);
  60. SheetMap.put((entry.getKey()), sheet.getSheetName());
  61. }
  62. }
  63. return SheetMap;
  64. }
  65. /**
  66. * 将某个工作表的某行转换为标题的Map实现类,并返回
  67. *
  68. * @param sheet 要解析的工作表 Sheet对象实现类
  69. * @param TitleRowIndex 标题位于哪一行
  70. * @return
  71. */
  72. private Map<Integer, Object> GetAnyRow2Title(Sheet sheet, int TitleRowIndex) {
  73. Map<Integer, Object> TitleMap = new LinkedHashMap<>();
  74. Row row = sheet.getRow(TitleRowIndex);
  75. GetCell(sheet, row, TitleMap);
  76. return TitleMap;
  77. }
  78. /**
  79. * 将将某个工作表的某行转换为除去标题的Map实现类的List集合,并返回
  80. *
  81. * @param sheet 要解析的工作表 Sheet对象实现类
  82. * @param TitleRowIndex 标题位于哪一行,默认标题以下部分是表格主体内容
  83. * @return
  84. */
  85. private List<Map<Integer, Object>> GetRows2ListWithMap(Sheet sheet, int TitleRowIndex) {
  86. List<Map<Integer, Object>> TableRows = new ArrayList<>();
  87. int rows = sheet.getPhysicalNumberOfRows();
  88. for (int r = TitleRowIndex+1; r < rows; r++) {
  89. Row row = sheet.getRow(r);
  90. if (row == null) {
  91. System.out.println("工作表:" + sheet.getSheetName() + ",第" + r + "行为空行!");
  92. } else if (row != null) {
  93. Map<Integer, Object> RowMap = new HashMap<>();
  94. GetCell(sheet, row, RowMap);
  95. TableRows.add(RowMap);
  96. }
  97. }
  98. return TableRows;
  99. }
  100. /**
  101. * 将Sheet、Row接口的实现类转换为特定格式的Map接口的实现类,并返回。
  102. * 转换后的Map实现类,-1位置作为工作表名,0位置作为行的序号,其余位置按照列的序号存到Map中。
  103. *
  104. * @param sheet 当前工作表,Sheet的实现类
  105. * @param columnrow 当前行,Row的实现类
  106. * @param columns 要存数据的Map实现类
  107. */
  108. private void GetCell(Sheet sheet, Row columnrow, Map<Integer, Object> columns) {
  109. if (columnrow == null) {
  110. System.out.println(sheet.getSheetName() + "中有空行!");
  111. return;
  112. }
  113. //-1位置作为工作表名
  114. columns.put(-1, sheet.getSheetName() + "");
  115. //0位置作为行的序号
  116. columns.put(0, columnrow.getRowNum() + "");
  117. //遍历Row对象,获取每行记录的每列
  118. for (int c = 0; c < columnrow.getLastCellNum(); c++) {
  119. Cell cell = columnrow.getCell(c);
  120. Object value = "";
  121. if (cell != null) {
  122. switch (cell.getCellType()) {
  123. //对不同类型的字段,用不同的方式获取
  124. case FORMULA:
  125. value = "" + cell.getCellFormula();
  126. break;
  127. case NUMERIC:
  128. value = cell.getNumericCellValue();
  129. break;
  130. case STRING:
  131. value = cell.getStringCellValue();
  132. break;
  133. case BLANK:
  134. value = "<BLANK>";
  135. break;
  136. case BOOLEAN:
  137. value = "" + cell.getBooleanCellValue();
  138. break;
  139. case ERROR:
  140. value = "" + cell.getErrorCellValue();
  141. break;
  142. default:
  143. value = "" + cell.getCellType();
  144. }
  145. //其余位置按照列的序号存到Map中
  146. columns.put(cell.getColumnIndex() + 1, value);
  147. }
  148. }
  149. }
  150. /**
  151. * 根据工作表的序号获取ExcelBean的实体类对象
  152. * @return ExcelBean
  153. */
  154. public List<ExcelBean> GetExcelBean(Map<Integer,Integer> SheetNum) {
  155. List<ExcelBean> excelBeans = new ArrayList<>();
  156. if(ExcelWorkbook != null){
  157. //获取所有工作表名称
  158. Map<Integer,Object> TitleMap = GetSheet2Map(SheetNum);
  159. //以工作表为单位来读取数据为实体类
  160. for(Map.Entry<Integer,Object> entry:TitleMap.entrySet()){
  161. ExcelBean excelBean = new ExcelBean();
  162. //将TitleMap的值写入工作表属性
  163. excelBean.setSheetname(entry.getValue().toString());
  164. //根据TitleMap的键获取Sheet对象
  165. Sheet sheet = ExcelWorkbook.getSheetAt(entry.getKey()-1);
  166. //默认行号为0
  167. int TitleNum = 0;
  168. if(SheetNum != null){
  169. //根据TitleMap的键到SheetNum中获取指定的行号
  170. TitleNum = SheetNum.get(entry.getKey())-1;
  171. }
  172. excelBean.setColumntitle(GetAnyRow2Title(sheet,TitleNum));
  173. excelBean.setRows(GetRows2ListWithMap(sheet,TitleNum));
  174. excelBeans.add(excelBean);
  175. }
  176. }else if(ExcelWorkbook == null){
  177. System.out.println("获取Workbook失败!");
  178. }
  179. return excelBeans;
  180. }
  181. /**
  182. * 关闭Workbook对象
  183. */
  184. public void Close(){
  185. try {
  186. ExcelWorkbook.close();
  187. } catch (IOException e) {
  188. e.printStackTrace();
  189. }
  190. }
  191. }

 3.测试类Test 

  1. package com.myself.pottest;
  2. import org.apache.poi.ss.usermodel.Row;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. public class Test {
  7. public static void main(String[] args) {
  8. String path ="D:\\书本.xls";
  9. ExcelParser excelpaser = new ExcelParser(path);
  10. excelpaser.Read();
  11. Map<Integer,Integer> SheetNum = new HashMap<>();
  12. //设置要读取的工作表顺序号及其对应的行号
  13. SheetNum.put(1,1);
  14. SheetNum.put(2,1);
  15. SheetNum.put(3,2);
  16. List<ExcelBean> excelBeanList = excelpaser.GetExcelBean(SheetNum);
  17. for(ExcelBean Eb:excelBeanList){
  18. System.out.println("工作表"+Eb.getSheetname());
  19. System.out.println("表头"+Eb.getColumntitle());
  20. List <Map<Integer, Object>> rowList = Eb.getRows();
  21. System.out.println("表格:");
  22. for(Map<Integer, Object> map:rowList){
  23. System.out.println(map);
  24. }
  25. }
  26. excelpaser.Close();
  27. }
  28. }

4.工具类功能描述

 输入Excel文件路径,程序自动识别xls和xlsx文件类型。根据预先设置的要读取的工作表顺序号及其对应的行号、读取Excel工作簿为ExcelBean的列表,工作表名为String,标题为Map<Integer, Object>,表格为List<Map<Integer, Object>>。

5.效果

表格数据

 运行结果

依赖的Jar包

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/709481
推荐阅读
相关标签
  

闽ICP备14008679号