POI是Apache基金会的提供的java实现的一套用于读取Excel、Word、PPT等文档的库,在实际项目中可能 很多地方都会用到Excel的读取,比如Excel的导入,我们不可能每个地方都单独实现一套Excel的读取方法,这时候就需要封装一个通用的类,只要有读取Excel的地方就调用该方法就可以了,下面我们就来实现它。

首先,为了提高可扩展性,也为了方便扩展到譬如Word、PPT这类文档,我们需要抽象出一个Template类,通过工厂方法来构建不同的Template。

然后,实现每个不同的Template,在实现过程中,我们还可以设置Listener,这样只要实现了该监听器,就能得到当前读取到的值,方便扩展。

OK,下面请看具体的代码:

import java.io.InputStream;
import java.io.Serializable;
import java.util.List;import cn.sunsharp.poi.bean.Filter;/*** The template of POI.* All template must inherit this class.* @author lynn**/
public abstract class Template {protected List<Filter> filters;protected boolean ignore = false;public void setFilters(List<Filter> filters) {this.filters = filters;}public List<Filter> getFilters() {return filters;}public boolean isIgnore() {return ignore;}public void setIgnore(boolean ignore) {this.ignore = ignore;}/*** parse the excel、ppt、word etc.* it is a abstract method.* you can implement it.* @param inputStream* @return* @throws Exception*/public abstract List<Serializable> parse(InputStream inputStream)throws Exception;public abstract void parse(InputStream inputStream,TemplateListener listener)throws Exception;
}
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import cn.sunsharp.poi.bean.Excel;
import cn.sunsharp.poi.bean.ExcelFilter;
import cn.sunsharp.poi.bean.Filter;class ExcelTemplate extends Template {@Overridepublic List<Serializable> parse(InputStream inputStream) throws Exception {OPCPackage pkg = null;List<Serializable> list = new ArrayList<Serializable>();try{pkg = OPCPackage.open(inputStream);XSSFWorkbook workbook = new XSSFWorkbook(pkg);int sheetNum = workbook.getNumberOfSheets();XSSFSheet sheet = null;XSSFRow row = null;XSSFCell cell = null;Excel excel = null;for (int i = 0; i < sheetNum; i++) {sheet = workbook.getSheetAt(i);if(null == sheet){continue;}for (int j = 0,rowNum = sheet.getLastRowNum(); j <= rowNum; j++) {row = sheet.getRow(j);if(null == row){continue;}for (int k = 0,cellNum = row.getLastCellNum(); k <= cellNum; k++) {cell = row.getCell(k);if(null == cell){continue;}excel = new Excel();excel.setSheetName(sheet.getSheetName());excel.setSheetIndex(i);excel.setCell(k);excel.setRow(j);excel.setValue(cell.toString());list.add(excel);}}}}finally{if(null != pkg){pkg.close();}}return filterData(list);}@Overridepublic void parse(InputStream inputStream,TemplateListener listener) throws Exception {if(null == listener){throw new NullPointerException("listener must not be null.");}List<Serializable> data = parse(inputStream);int size = 0;if(null != data && (size = data.size()) > 0){Excel excel = null;for (int i = 0; i < size; i++) {excel = (Excel)data.get(i);listener.callback(excel);}}}/*** ignore为true,则不读取filter指定的数据,为false则读取filter指定的数据* filter为空,则ignore参数失效,即读取所有数据* filter参数中,sheetIndex为空,则读取所有sheet,row为空,则读取所有row,cell为空,则读取所有cell*/private List<Serializable> filterData(List<Serializable> list){List<Serializable> data = new ArrayList<Serializable>();int size = 0;if(null != list && (size = list.size()) > 0){Excel excel = null;if(null != filters && filters.size() > 0){for (int i = 0; i < size; i++) {excel = (Excel)list.get(i);for (Filter item : filters) {ExcelFilter filter = (ExcelFilter)item;Integer sheetIndex = filter.getSheetIndex();Integer row = filter.getRow();Integer cell = filter.getCell();if(ignore){if(null != sheetIndex && sheetIndex.intValue() == excel.getSheetIndex()){continue;}if(null != row && row.intValue() == excel.getRow()){continue;}if(null != cell && cell.intValue() == excel.getCell()){continue;}data.add(excel);}else{//如果三个都有值if(null != sheetIndex && null != row && null != cell){if(sheetIndex.intValue() == excel.getSheetIndex() && row.intValue() == excel.getRow() && cell.intValue() == excel.getCell()){data.add(excel);}}//如果sheetIndex没有值,row和cell有值if(null == sheetIndex && null != row && null != cell){if(row.intValue() == excel.getRow() && cell.intValue() == excel.getCell()){data.add(excel);}}//如果row没有值,sheetIndex和cell有值if(null == row && null != sheetIndex && null != cell){if(sheetIndex.intValue() == excel.getSheetIndex() && cell.intValue() == excel.getCell()){data.add(excel);}}//如果cell没有值,sheetIndex和row有值if(null == cell && null != sheetIndex && null != row){if(sheetIndex.intValue() == excel.getSheetIndex() && row.intValue() == excel.getRow()){data.add(excel);}}//如果只有sheetIndex有值if(null == row && null == cell && null != sheetIndex){if(sheetIndex.intValue() == excel.getSheetIndex()){data.add(excel);}}//如果只有row有值if(null == cell && null == sheetIndex && null != row){if(row.intValue() == excel.getRow()){data.add(excel);}}//如果只有cell有值if(null == sheetIndex && null == row && null != cell){if(cell.intValue() == excel.getCell()){data.add(excel);}}}}}}else{data.addAll(list);}}return data;}}
import java.io.Serializable;/*** template listener* you can implement this interface to push to your custom class.* @author lynn**/
public interface TemplateListener {public void callback(Serializable entity);}
import cn.sunsharp.poi.enumeration.POI;public class TemplateFactory {/*** via the factory to create template* @param poi* @return*/public static Template create(POI poi){switch(poi){case Excel:return new ExcelTemplate();case PPT:break;case Word:break;case PDF:break;}return null;}
}
public enum POI {Excel,PPT,Word,PDF
}
import java.io.Serializable;/*** the excel bean.* @author administrator**/
public class Excel implements Serializable {private static final long serialVersionUID = -7606795591653370811L;private String sheetName;private int sheetIndex;private int row;private int cell;private String value;public String getSheetName() {return sheetName;}public void setSheetName(String sheetName) {this.sheetName = sheetName;}public int getSheetIndex() {return sheetIndex;}public void setSheetIndex(int sheetIndex) {this.sheetIndex = sheetIndex;}public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getCell() {return cell;}public void setCell(int cell) {this.cell = cell;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}@Overridepublic String toString() {return "Excel [sheetName=" + sheetName + ", sheetIndex=" + sheetIndex+ ", row=" + row + ", cell=" + cell + ", value=" + value + "]";}}
public class Filter {}
public class ExcelFilter extends Filter {private Integer sheetIndex;private Integer row;private Integer cell;public static Builder options(){return new Builder();}public static class Builder{private Integer sheetIndex;private Integer row;private Integer cell;public Builder setSheetIndex(Integer sheetIndex){this.sheetIndex = sheetIndex;return this;}public Builder setRow(Integer row){this.row = row;return this;}public Builder setCell(Integer cell){this.cell = cell;return this;}public ExcelFilter build(){return new ExcelFilter(this);}}private ExcelFilter(Builder builder){this.sheetIndex = builder.sheetIndex;this.row = builder.row;this.cell = builder.cell;}public Integer getSheetIndex() {return sheetIndex;}public Integer getRow() {return row;}public Integer getCell() {return cell;}@Overridepublic String toString() {return "ExcelFilter [sheetIndex=" + sheetIndex + ", row=" + row+ ", cell=" + cell + "]";}}

通过以上代码,我们发现,在Template有Filter和ignore两个属性,Filter是过滤器,ignore如果为true,则不读取filter指定的数据,ignore为false,则只读取filter指定的数据,

这样就完成了比较优雅的可扩展的Excel读取,我们如果要读取PPT,就构建一个PPTTemplate来实现Template抽象类即可。下面请看测试类:

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;import cn.sunsharp.poi.bean.Excel;
import cn.sunsharp.poi.bean.ExcelFilter;
import cn.sunsharp.poi.bean.Filter;
import cn.sunsharp.poi.enumeration.POI;
import cn.sunsharp.poi.template.Template;
import cn.sunsharp.poi.template.TemplateFactory;
import cn.sunsharp.poi.template.TemplateListener;public class Test implements TemplateListener{public static void main(String[] args) throws Exception{new Test().testExcel();}private List<String> headers = new ArrayList<String>();private void testExcel()throws Exception{String path = "C:\\Users\\administrator.YCSPC017\\Desktop\\农产品行业体系新旧编码对比.xlsx";Template template = TemplateFactory.create(POI.Excel);List<Filter> filters = new ArrayList<Filter>();ExcelFilter filter = ExcelFilter.options().setRow(0).setSheetIndex(2).build();filters.add(filter);
//      filter = ExcelFilter.options()
//              .setRow(1)
//              .setSheetIndex(1)
//              .setCell(1)
//              .build();
//      filters.add(filter);template.setFilters(filters);template.setIgnore(false);InputStream inputStream = new FileInputStream(path);template.parse(inputStream,this);System.out.println(headers);}@Overridepublic void callback(Serializable entity){Excel excel = (Excel)entity;headers.add(excel.getValue());}}
import java.io.Serializable;public class Category implements Serializable{private static final long serialVersionUID = 2348166129263260641L;private String name;private String id;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Category [name=" + name + ", id=" + id + "]";}}

如果有问题,可以给我留言哦!

POI实现一个通用的Excel读取模板相关推荐

  1. POI如何使用已有Excel作为模板二三事

    关于POI POI是Apache的一个开源项目,起初的目标是允许用户使用java代码来对Excel进行操作,发展到今天POI本身支持的范围已经逐步扩展到对Microsoft Office主要产品,包括 ...

  2. 【自动化测试】搭建一个简单从Excel读取用例内容并输出结果的脚本

    # -*- coding:utf-8 -*- from selenium import webdriver import xlrd import xlwt from xlutils.copy impo ...

  3. 最详细使用vue-cli创建一个通用的vue项目模板

    1.首先安装vue-cli 官网提供两种安装方法 npm install -g @vue/cli # OR yarn global add @vue/cli 2.安装成功之后 vue create d ...

  4. JAVA POI通用Excel导入模板

    JAVA POI通用Excel导入模板 Excel导入模板类 Excel导入模板类 package com.golte.dataform.analysis.controller;import com. ...

  5. POI之excel固定模板导出

    POI之excel固定模板导出 一.简介 二.excel模板 三.项目中maven依赖 四.Excel模板操作代码 五.Controller层excel模板导出接口代码 六.导出excel 一.简介 ...

  6. Java POI SXSSFWorkbook 读取模板,输出

    Java POI 用 SXSSFWorkbook 读取模板,输出 公司的项目,用户投诉,说只要点击模板下载功能,就会导致整个服务全部停掉. 之前这个功能由于数据量并没有那么多,所以一直都没有发生过这种 ...

  7. 「实战教程」如何使用POI读取模板PPT填充数据并拼接至目标文件

    文章目录 一.PPT文件格式介绍 1.PPT文件格式的概述 2.HSLF和XSLF的区别 3.如何选择合适的POI类库 二.SlideShow 三.读取PPT文件 1. 加载PPT文件 2. 获取PP ...

  8. jxls读取模板导出Excel学习笔记

    jxls读取模板导出Excel学习笔记 ​ jxls是一个简单的.轻量级的excel导出库,使用特定的标记在excel模板文件中来定义输出格式和布局.除此以外,java中成熟的excel导出工具有po ...

  9. JS操作Excel读取和写入(模板操作)

    前一段时间一直在做报表,所以肯定会用到Excel的操作,但是在网上查阅资料有关JS操作excel较少,有的话,也都是老生常谈或很零碎的一些东西.本人是在实际项目中摸索出,JS读写Excel(模板)数据 ...

最新文章

  1. 机器学习—决策树构造算法的python实现
  2. java的初始化顺序
  3. js三元运算符_这些优化技巧可以避免我们在 JS 中过多的使用 IF 语句
  4. 【译】BINDER - ANALYSIS AND EXPLOITATION OF CVE-2020-0041
  5. 蓝桥杯 I.双向排序
  6. JAVA UDP网络编程学习笔记
  7. Linux存储保护,谈谈Linux中的存储保护
  8. python中的常量可以修改吗_深入理解Python变量与常量
  9. electronjs设置宽度_javascript – 如何使Electron WebView填充指定的大小?
  10. 如何正确的使用WinRAR,去除错误弹框
  11. c# 数据库操作学习
  12. [Data Pump]expdp导出笔记
  13. python使用-Python 应该怎么去练习和使用?
  14. oracle10gdmp字符集,从Export DMP文件看导出字符集(上)
  15. CREO:CREO软件的简介、安装(七大步骤)、学习路线大全(CREO软件各模块界面解释—菜单栏快速栏工作区、草绘/零件/工程图/装配设计讲解)、案例应用(几十个案例)之详细攻略
  16. 分形理论在图像处理中的应用研究(综述)
  17. max3232ese_【MAX3232ESE+ PDF数据手册】_中文资料_引脚图及功能_(美信 Maxim Integrated)-采芯网...
  18. 在家怎么免费下载论文、专利及标准?
  19. 献给正在纠结的朋友——转产品还是转测试
  20. MSP430F149IPMR

热门文章

  1. pi/4dqpsk的matlab及FPGA仿真
  2. 计算机教师专业发展规划,教师个人专业发展三年规划(2020-2023)
  3. 计算机课电脑如何提网速,教大家怎么调网速,让你的电脑像飞速运转。
  4. 微信小程序 消除图片拼接接缝
  5. 如何正确计算LINUX内存使用率
  6. Android 设置黑白滤镜
  7. SpringCloud快速上手
  8. termux播放mp3音频
  9. Mac上重装PHP-7.3和apache-2.4.41
  10. 海康服务器获取cms信息失败,织梦CMS文档读取频道信息失败,无法进行后续操作!...