• Java之POI的excel导入导出


      一、Apache POI是一种流行的API,它允许程序员使用Java程序创建,修改和显示MS Office文件。这由Apache软件基金会开发使用Java分布式设计或修改Microsoft Office文件的开源库。它包含类和方法对用户输入数据或文件到MS Office文档进行解码。

      二、基本结构

      HSSF - 提供读写Microsoft Excel格式档案的功能。
      XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
      HWPF - 提供读写Microsoft Word格式档案的功能。
      HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
      HDGF - 提供读写Microsoft Visio格式档案的功能。
      三、这里我们只介绍xls,2003版的excel导入导出
      1)导入需要的依赖包(pom.xml)
          <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.17</version>
            </dependency>

      2)简单介绍一下excel的导入方式

     public static void main(String[] args) throws Exception {
            //读取文件
            File file = new File("d:\test.xls");
            InputStream inputStream = new FileInputStream(file);
            //使用POI的流处理数据
            POIFSFileSystem poifsFileSystem = new POIFSFileSystem(inputStream);
            //声明2003版excel的文件读取方式
            HSSFWorkbook hssfWorkbook = new HSSFWorkbook(poifsFileSystem);
            //获取第一个sheet页
            HSSFSheet sheetAt = hssfWorkbook.getSheetAt(0);
            //获取数据总行数
            int rows = sheetAt.getPhysicalNumberOfRows();
            //每行数据处理
            for (int i = 0; i < rows; i++) {
                //获取一行数据
                HSSFRow row = sheetAt.getRow(i);
                if (i == 0) {
                    //这个主要用于标题
                    System.out.println(row.getCell(0));
                    continue;
                }
                //获取一行数据
                Iterator<Cell> cellIterator = row.cellIterator();
                List<Cell> cells = IteratorUtils.toList(cellIterator);
                System.out.println(cells);
            }
    
        }

      3)根据上面的基本实现功能封装了一些,工具类,主要目的是方便应用

      a、加入需要的工具依赖包(pom.xml)

        <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
                <version>1.9.3</version>
            </dependency>

      说明:这个东西主要是用来做数据对考的

      b、需要的实体类(这个类的目的就是用来保存excel中需要修改的一些参数位置)

    import java.util.List;
    import java.util.Map;
    
    public class ExcelParams {
    
        //sheet页数目
        private Integer sheetNum = 0;
        //实体名称
        private String entityName;
        //保存实体名称行数
        private Integer clazzNum = 0;
        //字段行数
        private Integer columnNum = 1;
        //开始数据读取的行数
        private Integer dataNum = 3;
        //开始读取列
        private Integer readColNum = 0;
        //读取的excel数据
        private List<Map<String, Object>> excelList;
        //最终数据处理
        private List<Map<String, Object>> excelHandleList;
    
        public Integer getSheetNum() {
            return sheetNum;
        }
    
        public void setSheetNum(Integer sheetNum) {
            this.sheetNum = sheetNum;
        }
    
        public String getEntityName() {
            return entityName;
        }
    
        public void setEntityName(String entityName) {
            this.entityName = entityName;
        }
    
        public Integer getClazzNum() {
            return clazzNum;
        }
    
        public void setClazzNum(Integer clazzNum) {
            this.clazzNum = clazzNum;
        }
    
        public Integer getColumnNum() {
            return columnNum;
        }
    
        public void setColumnNum(Integer columnNum) {
            this.columnNum = columnNum;
        }
    
        public Integer getDataNum() {
            return dataNum;
        }
    
        public void setDataNum(Integer dataNum) {
            this.dataNum = dataNum;
        }
    
        public Integer getReadColNum() {
            return readColNum;
        }
    
        public void setReadColNum(Integer readColNum) {
            this.readColNum = readColNum;
        }
    
        public List<Map<String, Object>> getExcelList() {
            return excelList;
        }
    
        public void setExcelList(List<Map<String, Object>> excelList) {
            this.excelList = excelList;
        }
    
        public List<Map<String, Object>> getExcelHandleList() {
            return excelHandleList;
        }
    
        public void setExcelHandleList(List<Map<String, Object>> excelHandleList) {
            this.excelHandleList = excelHandleList;
        }
    
    }

      excel模板的基本方式:

      

       说明:1、前面的序列号,是我为了方便理解加上去的,实际中不用加

          2、第一行中的数据为需要保存的实体名路径,后续再保存的时候需要用到

          3、第二行是字段主要用于数据的对考,对考到具体的实体中

          4、第三行就是给输入数据的人员展示的,第四行开始就是具体的数据了

      c、数据处理接口

    import com.troy.excel.domain.ExcelParams;
    
    public interface ExcelHandle {
    
        ExcelParams excelDataHanle(ExcelParams excelParams);
    }

      说明:这个接口目前没有实现方法。提供出来的目前是用于数据处理。自己在处理数据的时候写入数据处理的方式

      d、具体的解析过程和实体保存过程

      /**
         * excel导入功能
         * @param file
         * @param excelParams
         * @param excelHandle
         * @return
         * @throws Exception
         */
        public static ExcelParams excelImport(File file, ExcelParams excelParams, ExcelHandle excelHandle) throws Exception {
            //获取文件流
            InputStream inputStream = new FileInputStream(file);
            //通过poi的方式进行读取
            POIFSFileSystem poifsFileSystem = new POIFSFileSystem(inputStream);
            //声明工作簿
            HSSFWorkbook hssfWorkbook = new HSSFWorkbook(poifsFileSystem);
            //进入sheet页
            HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(excelParams.getSheetNum());
            //读取实体名称数据
            HSSFRow entityRow = hssfSheet.getRow(excelParams.getClazzNum());
            HSSFCell entityName = entityRow.getCell(excelParams.getReadColNum());
            excelParams.setEntityName(entityName.getStringCellValue());
            //读取数据保存到list中
            List<Map<String,Object>> excelList = new ArrayList<>();
            //获取字段数据
            HSSFRow colunmRow = hssfSheet.getRow(excelParams.getColumnNum());
            List<Cell> colums = IteratorUtils.toList(colunmRow.cellIterator());
            //读取excel数据
            for (int i = excelParams.getDataNum(); i < hssfSheet.getPhysicalNumberOfRows(); i++) {
                //获取某一行的数据
                HSSFRow excelRow = hssfSheet.getRow(i);
                Map<String, Object> map = new HashMap<>();
                for (int j = 0; j < excelRow.getPhysicalNumberOfCells(); j++) {
                    if (colums != null && colums.size() > j) {
                        HSSFCell rowCell = excelRow.getCell(j);
                        //设置类型的目的方便数据装换
                        rowCell.setCellType(CellType.STRING);
                        map.put(colums.get(j).getStringCellValue(), rowCell.getStringCellValue());
                    }
                }
                excelList.add(map);
            }
            //放入数据放入下一步处理
            excelParams.setExcelList(excelList);
            //ExcelHandle接口用来做进一步数据处理,要求必须重写
            excelHandle.excelDataHanle(excelParams);
            return excelParams;
        }

      说明:ExcelHandle 为接口在使用的时候必须重写才可以实现

      /**
         * 保存excel数据
         * @param excelParams
         * @return
         */
        public static void saveExcelList(ExcelParams excelParams, EntityManager entityManager) throws Exception {
            //1、获取保存的对象
            Class<?> clazz = Class.forName(excelParams.getEntityName());
            //2、保存数据
            for (Map<String, Object> map:excelParams.getExcelHandleList()) {
                //对考数据
                Object object = clazz.newInstance();
                BeanUtils.populate(object, map);
                //保存数据
                entityManager.persist(object);
            }
        }

      说明:BeanUtils提供了map到实体的拷贝,当然其他Gson,Fastjson也是可以实现的。

           entityManager.persist(object)是hibernate中保存对象的方法

       e、测试方法

    public static void main(String[] args) throws Exception {
            //读取文件
            File file = new File("d:\test.xls");
            //声明参数
            ExcelParams excelParams = new ExcelParams();
            excelParams.setSheetNum(0);
            excelParams.setClazzNum(0);
            excelParams.setColumnNum(1);
            excelParams.setDataNum(3);
            excelParams.setReadColNum(0);
            //导如数据
            ExcelParams excelData = ExcelUtil.excelImport(file, excelParams, (ep) -> {
                //重写具体的实现方法
                ep.setExcelHandleList(excelParams.getExcelList());
                return ep;
            });
            //保存实体,这里需要加入到事物中,我这里没有具体测试
            ExcelUtil.saveExcelList(excelData, null);
            System.out.println(excelParams.getExcelList());
        }

      4)导出功能,导出功能相对简单。我就写了一个简单的实现过程,供理解。当然里面的样式这些,我不细说,自己研究

      /**
         * excel数据导出
         * @param title
         * @param datas
         * @param out
         * @param <T>
         * @throws Exception
         */
        public static <T> void excelExport(String title, List<T> datas, OutputStream out) throws Exception {
            //声明一个工作簿
            HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
            //设置一个sheet名词
            HSSFSheet hssfSheet = hssfWorkbook.createSheet(title);
            //数据处理,通过out写出
            for (int i = 0; i < datas.size(); i++) {
                //创建行数,主要是创建在第几行
                HSSFRow hssfRow = hssfSheet.createRow(i);
                //获取T的字段数
                Field[] fields = datas.get(i).getClass().getDeclaredFields();
                for (int j = 0; j < fields.length; j++) {
                    //获取字段名称
                    String fieldName = fields[j].getName();
                    //获取get方法
                    String methodName = "get"+ fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
                    Method method = datas.get(i).getClass().getMethod(methodName);
                    //执行get方法获取对应数据
                    Object text = method.invoke(datas.get(i));
                    //加入到对应单元格
                    HSSFCell hssfCell = hssfRow.createCell(j);
                    if (text != null) {
                        hssfCell.setCellValue(text.toString());
                    }
                }
            }
            //写入到输出流中
            hssfWorkbook.write(out);
        }

      测试方法:

       public static void main(String[] args) throws Exception {
            OutputStream outputStream = new FileOutputStream("d:\1.xls");
            String title = "用户数据";
            List<User> users = new ArrayList<>();
            for (int i = 1; i <= 10; i++) {
                User user = new User();
                user.setId(i);
                user.setName("name"+i);
                users.add(user);
            }
            ExcelUtil.excelExport(title, users, outputStream);
        }

      四、基本上实现过程都在里面,具体的封装过程可以自己参考一下

      五、源码下载:https://pan.baidu.com/s/1dahdRS

  • 相关阅读:
    nginx
    git命令
    mysql的优化
    nginx下的负载均衡
    IO模式和IO多路复用
    回顾java基础—Java数据类型
    解决jdk1.8上编译dubbo失败
    KB,Kb单位换算,网络带宽中的Kbps和KB/s到底是什么意思? (注:B和b的区别)
    生成器函数_yield_yield from_send
    推导式_集合
  • 原文地址:https://www.cnblogs.com/ll409546297/p/8288519.html
Copyright © 2020-2023  润新知