zoukankan      html  css  js  c++  java
  • 【POI】java对excel的读写操作

    在工作中需要将mongo中的数据导出到excel中,所以根据需要学习了poi。以下为学习内容的总结:

    1.POI是什么?

    • poi是Apache团队开发的专门面对用java处理Excel文档的工具。
    • 官网地址:https://poi.apache.org/
    • 在操作exccel有HSSFWorkbook和XSSFWorkbook两种方式。两种方式的区别在于根据excel的版本不同,一个简单的方式就是后缀为.xls为HSSFWorkbook;后缀为.xlsx为XSSFWorkbook

    2.输出Excel操作流程

    • 此部分通过代码解释使用POI将集合导出Excel的流程,在下一节中详细解释。
       /**
         * 将集合转化为Excel表格
         */
        public void getExcel(List<List<String>> list) throws IOException {
            //1.标题
            String[] title = {"招聘名称", "投递邮箱", "信息来源", "信息城市", "来源网站"};
            //2.文件名
            String fileName = new String("企业邮箱信息.xls".getBytes(), "utf-8");
            //3.sheet名
            String sheetName = new String("梧桐果、海投网、我司企业邮箱信息".getBytes(), "utf-8");
    
            // 1.创建一个HSSFWorkbook,对应一个Excel文件
            HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
            // 2.在workbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet sheet = hssfWorkbook.createSheet(sheetName);
            // 3.在sheet中添加表头第0行,也就是标题行
            HSSFRow row = sheet.createRow(0);
            // 4.创建单元格,并设置单元格格式
            HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//样式为中心水平对齐
            
            //5.创建列单元格
            for (int i = 0; i < title.length; i++) {
                HSSFCell cell = row.createCell(i);
                cell.setCellValue(title[i]);
                cell.setCellStyle(cellStyle);
            }//表头
    
            for (int y = 0; y < list.size(); y++) {
                HSSFRow row1 = sheet.createRow(y + 1);//创建行
                List<String> strings = list.get(y);
                for (int x = 0; x < title.length; x++) {
                    HSSFCell cell = row1.createCell(x);
                    cell.setCellValue(strings.get(x));
                    cell.setCellStyle(cellStyle);//创建列
                }
            }
    
            File file = new File("C:\Users\bxk\Desktop\" + fileName);
            OutputStream outputStream = new FileOutputStream(file);
            hssfWorkbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        }

     3.输出Excel操作步骤详解

    3.1创建出所需的文件信息

            //1.标题
            String[] title = {"招聘名称", "投递邮箱", "信息来源", "信息城市", "来源网站"};
            //2.文件名
            String fileName = new String("企业邮箱信息.xls".getBytes(), "utf-8");
            //3.sheet名
            String sheetName = new String("我是一个sheet名称".getBytes(), "utf-8");

    3.2 创建WorkBook

     HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); //对应一个Excel文件

      demo:如下文就可以生成一个空白的、名为workbook的xlsk文档。注意当文件名为中文的时候可能会出现乱码。使用 new String("中文","utf-8") ,将解决乱码问题。

    HSSFWorkbook wb = new XSSFWorkbook(); try (OutputStream fileOut = new FileOutputStream("workbook.xlsx")) { wb.write(fileOut); }

    3.3创建Sheet

    HSSFSheet sheet = hssfWorkbook.createSheet(sheetName);//对应Excel文件中的sheet   其中sheetName不能为 "" ,不能为 Null

     值得注意的是,创建的过程中不会覆盖。每一个sheet都是独立的,就算此sheet并没有使用,也不会消失,而是叠加。

    String safeName = WorkbookUtil.createSafeSheetName("");//这样创建的sheetName ""会转化为empty,null会转化为“null

    这个sheet我当时也找了好一会,可能是实在是不熟悉Excel。sheet就表示excel中的某一张表,当然既然是表,就会有表名。所以sheetName的作用就是显示表名。上截图解释具体位置。

     3.4创建表头

    HSSFRow row = sheet.createRow(0);// 在sheet中添加表头第0行,也就是标题行

     3.5创建单元格样式

    HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
    cellStyle.setAlignment(HorizontalAlignment.CENTER);//样式为中心水平对齐 还有其他样式都在 HorizontalAlignment 中,可以自行查找。
    
    

     3.6创建列单元格

    for (int i = 0; i < title.length; i++) {
                HSSFCell cell = row.createCell(i);
                cell.setCellValue(title[i]);
                cell.setCellStyle(cellStyle);
            }//表头

     在poi中对于excel的操作,只有行操作:定位到某一行,进行具体操作。所以就需要得到行元素HSSFRow ,在根据 HSSFCell  定位到某行的第某个单元格。

    3.7创建数据

    for (int y = 0; y < list.size(); y++) {
                List<String> strings = list.get(y);
                if (strings.get(0).toString().indexOf("海投") != -1 || strings.get(0).toString().indexOf("梧桐果") != -1) {
                    continue;
                }
                HSSFRow row1 = sheet.createRow(y + 1);//创建行
                for (int x = 0; x < title.length; x++) {
                    HSSFCell cell = row1.createCell(x);
                    cell.setCellValue(strings.get(x));
                    cell.setCellStyle(cellStyle);//创建列
                }
            }

    3.8打印输出

      File file = new File("C:\Users\bxk\Desktop\" + fileName);
      OutputStream outputStream = new FileOutputStream(file);
      hssfWorkbook.write(outputStream);
      outputStream.flush();
      outputStream.close();

    此处有个小提示,在idea中输出输入流或者HSSFWorkbook 等创建后,没有close的都会标红,看着实在是难受。可以try后在finally中进行close,可以解决标红。

    4读取excel文件

    为什么又学习了读取excel呢,就是因为我感觉爬虫的数据不够完美,打算重新爬一边,就把数据库删了....。然后那个数据一时半会也爬不下来。

    (爬不下来的原因:1.爬的速度太快,ip被封,就算后来设置了得到一个数据暂停一秒也不可以。。。2.在西刺网得到一些服务器的ip和端口号,借助这些服务器去帮我爬取数据。可是这些服务器不稳定 ,有时会出现连接超时等错误,就需要手动重启项目。很麻烦。有一个想法:就是当运行出现超时错误时,重启项目。刚好设计模式中的观察者模式可以解决这个问题)

    所以我就换了一个方法。。。重新读取导出的excel数据,将数据重新切割进行保存。

    这个事情告诉我,删数据库之前,一定要做好备份。。。

        /**
         * 读取我司数据库 中的数据 C:UsersxkDesktop企业邮箱信息(我司数据里).xls
         */
        public List<List<String>> getExcelDateToAddress() {
            ArrayList<List<String>> lists = new ArrayList<>();
            Workbook wb = null;
            InputStream inp = null;
            try {
                inp = new FileInputStream("C:\Users\bxk\Desktop\数据.xls");
                wb = new HSSFWorkbook(inp);  //读取excel文件
                Sheet sheetAt = wb.getSheetAt(0);  //得到第一个sheet文件,
                Iterator<Row> rowIterator = sheetAt.rowIterator();  //得到行数的迭代器
                while (rowIterator.hasNext()) {
                    ArrayList<String> strings = new ArrayList<>();
                    Row next = rowIterator.next();
                    Iterator<Cell> cellIterator = next.cellIterator();
                    while (cellIterator.hasNext()) {  //得到单元格的迭代器
                        Cell next1 = cellIterator.next();
                        String stringCellValue = next1.getStringCellValue();
                        strings.add(stringCellValue);
                    }
                    strings.set(3, getCity(strings.get(3)));
                    lists.add(strings);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    wb.close();
                    inp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return lists;
        }

    这个很简单,就不详细解释了。当poi读取到文件后,就会分析出sheet、行数等消息。但是我找了好半天也没有得到行数的接口。想要读取每行的信息,只能通过迭代器。

    打开官网(上面有链接)——API介绍(Component)——快速指南(Quick Guide) 也能看到详细的例子和解释哦。

  • 相关阅读:
    路由的添加和删除
    extjs中的tabpanle下的combobox提交问题
    Asp.net下from认证统一认证配置
    ASP.NET权限管理系统(FrameWork) 1.0.8 Release
    Web网站架构设计
    手机6120C 玩仙剑dos版
    Extjs 4.07 对类型定义引发的匹配问题
    Supesoft权限管理系统(FrameWork) 1.0.9 Release
    Google静态地图如何显示两点之间路线1(简单路线)
    Chrome不支持showModalDialog模态对话框和无法返回returnValue的问题
  • 原文地址:https://www.cnblogs.com/miaoww/p/9337349.html
Copyright © 2011-2022 走看看