• Java操作excel


      前两天遇到一个这样的任务,需要将十多个Excel按指定模板整理,这种情况首先想到的就是用程序去解决这件事,人工的话,不仅费时费力,而且准确度不一定高,偶尔马虎一下,很难再去发现,最主要的是我们人力不够,就两个人,要整的话得一两天的工作量,但是领导给的时间也不是很多,遂用代码解决。
      一开始想到的是用python去写,但是换了电脑后还没装python环境,而且用python也不是特别多,写的话肯定是一边写一边学,如果时间充裕的话,这是最好的解决办法,但是奈何时间不是很多,就直接拿java写了。
      之前写过用java读取excel,这次是在两个excel间对比,写入第三个excel,涉及到整列数据的读取写入,两个sheet页首行数据的对比,多个sheet页之间的操作等。
      没写之前不知道,写完之后发现java操作excel还是比较不友好的,主要包括两点,
      1.java操作excel一般是用poi操作,poi操作不支持整列操作,一般都是按行操作,所以对于我的需求就比较难受了,每次操作列只能先读行,再读列,写入同理;
      2.一开始设想的是按列操作完成之后,保存再写入下一列,但是发现新建excel时写入数据没问题,但是再追加数据就不行了,网上找了半天,只发现两种解决方法,很不幸,都不行;
      对于第一种情况,没有办法,只能先读行,再读列,难受也没办法;对于第二种情况,有两种解决办法,要么就是读取完整个excel后再写入,要么就是读取原excel,然后增加要写入的数据,再写入到新的文件中,我是用第一种方法,通过二维数组记录下整个要写入的表格,然后通过二维数组写入到表格中。
    现在记录下中间关键的几个操作点:

    1. 读取文件列表:
      // 读取某目录
      File dir = new File(strPath);
      // 获取文件夹下某所有文件
      File[] files = dir.listFiles();
    
    1. 读取Excel文件
            // 新建文件流
            FileInputStream templateFileInputStream = null;
            // 新建sheet对象
            XSSFWorkbook sheets = null;
            // 新建excel行
            XSSFRow row = null;
            try {
                // 读取文件流
                templateFileInputStream = new FileInputStream(filePath);
                // 解析xlsx格式文件
                sheets = new XSSFWorkbook(templateFileInputStream);
                // 获取指定sheet
                XSSFSheet sheet = sheets.getSheetAt(sheetIndex);
                // 获取第一行
                row = sheet.getRow(0);
                // 获取当前行包含列数
                int columns = row.getPhysicalNumberOfCells();
                // 获取当前表格行数
                int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
                jsonObject.put("row", row);
                jsonObject.put("columns", columns);
                jsonObject.put("rows", physicalNumberOfRows);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (templateFileInputStream != null) {
                    templateFileInputStream.close();
                }
            }
    
    1. 写入excel文件
            //1、判断文件是否存在,存在的话,就追加新的sheet页,不存在就新建
            FileOutputStream out = null;
            // 声明一个工作薄
            XSSFWorkbook workbook = null;
            try {
                out = new FileOutputStream(newFilePath);
                workbook = new XSSFWorkbook();
                // 生成一个表格
                XSSFSheet sheet = workbook.createSheet(title);
                // array是要写入的二维数组,可以换成其他
                for (int i = 0; i < array[0].length; i++) {
                	// a是我代码中的一个值,createRow这个方法是创建下标为a的行
                    XSSFRow row = sheet.createRow(a);
                    for (int j = 0; j < array.length; j++) {
                        XSSFCell cell = row.createCell(j);
                        cell.setCellValue(array[j][i]);
                    	}
                // 将建好的sheet写入到excel中
                workbook.write(out);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (out != null) {
                    out.close();
                }
            }
    
    1. 单元格类型判断
            switch (cell.getCellTypeEnum()) {
                case STRING:
                    temp = cell.getRichStringCellValue().getString();
                    break;
                case NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        Date date = cell.getDateCellValue();
                        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                        temp = df.format(date);
                    } else if (!String.valueOf(cell.getNumericCellValue()).contains("E")) {
                        return String.valueOf(cell.getNumericCellValue());
                    } else {
                        // 对超长字符串进行格式化处理
                        return new DecimalFormat("#").format(cell.getNumericCellValue());
                    }
                    break;
                case BLANK:
                    temp = "";
                    break;
                default:
                    temp = cell.toString();
                    break;
            }
    

      已上就是处理的主要步骤,不过因为时间原因代码只实现了主要功能,算是半自动化吧,还得手动切换数据模板,不过这样已经可以顺利完成任务了,比全自动慢了一丢丢,从上边的2,3点就可以看出为什么支持追加了,对于同一个文件,不可能同时对它进行读入流和写入流操作,所以不能追加,再后边第四点写的比较简单,因为当前数据格式不是很多,这几个足以满足要求,如果有需要可以去网上找下,有不少例子可以参考。

    金无足赤,人无完人,若有文章什么问题欢迎各位批评指正,共同交流,共同进步。 另,人过留名,雁过留声,少侠觉得还行的话留下个赞吧!:)
  • 相关阅读:
    ArcGIS Engine开发-三维视图(SceneControl)的刷新
    c#开发基础知识及有用技巧(一)
    ArcGIS Engine开发-取得ArcMap文档缩略图
    RichTextBox中表格不能折行的问题
    Windows WorkFlow Foundation入门(六) 编译工作流
    你还在用 VMware?快试试这款更轻量级的虚拟机!
    RedisJson 横空出世,性能碾压 ES 和 MongoDB!NoSQL 要变天了吗?
    基于 ElasticSearch 实现站内全文搜索,写得太好了!
    团灭!Log4j 1.x 也爆雷了。。。速速弃用!!
    Spring Boot + Redis:抗住 10w 人,秒杀抢单!
  • 原文地址:https://www.cnblogs.com/thePeaceOftheLord/p/15570199.html
Copyright © 2020-2023  润新知