zoukankan      html  css  js  c++  java
  • java通过apache poi框架读取2007版Excel文件

    java系读写excel文件既可以用jxl库,也可以用POI库,但是,jxl库只支持低版本的excel2003,不支持更高版本,无法直接输出*.xlsx文件,只能输出*.xls文件,另外,更新也不频繁。所以,目前大多采用POI库。

    jxl库官网:http://jxl.sourceforge.net/

    POI介绍
    要想使用POI对Excel进行操作,我们需要先了解一下Excel的两种版本:一种是97-2003版本扩展名是“.xls”;一种是2007版本扩展名是“.xlsx”。POI分别针对这两种版本需要导入的jar包不同,操作类也不同。

    HSSF:操作的是.xls;XSSF:操作的是.xlsx。

    不管哪种操作,基本思路都是一致,先要对应一个Excel文件,然后在对应文件中的某个sheet,接下来在操作某一行和这一行中的某一列。对应POI包:文件(webbook)、sheet(sheet)、行(row)和具体单元格(cell)。

    详细操作请参照POI官网的Excel(HSSF/XSSF)操作。此外,还有EasyPOI,功能与POI差不多,Easypoi的目标不是替代poi,而是让一个不懂导入导出的快速使用poi完成Excel和word的各种操作,而不是看很多api才可以完成这样工作。

    下面给出我的测试用例源码。

    1、将工程所需要的poi库(本测试的版本poi-bin-4.1.2-20200217.zip)中的lib文件添加进来,并添加到Build Path中,如下图:

    2、工程源代码:

    package com.reus;
    
    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.math.BigDecimal;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.TimeZone;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;
    
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellType;
    import org.apache.poi.ss.usermodel.DateUtil;
    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;
    
    public class ExcelOperate {
    
        public static void main(String[] args) {
            String[][] data = { { "中文", "$1275.00" }, { "Pets", "$125.00" }, { "Electronics", "$2533.00" }, { "Mensware", "$497.00" } };
            String[] headers = { "Department", "Daily Revenue" };
            JFrame frame = new JFrame("JTable to Excel Hack");
            DefaultTableModel model = new DefaultTableModel(data, headers);
            final JTable table = new JTable(model);
            JScrollPane scroll = new JScrollPane(table);    
            String outFullPath = "out.xlsx";//默认输出到工程本地目录下
    
            JButton exportButton = new JButton("输出");//输出为Excel文件
            exportButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    try {
                        createExcel(model,outFullPath);//输出并创建Excel
                    } catch (Exception ex) {
                        System.out.println(ex.getMessage());
                        ex.printStackTrace();
                    }
                }
            });
            
            JButton readButton = new JButton("读取");//读取Excel文件,在控制台窗口打印显示
            readButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    try {        
                        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SS");
                        TimeZone t = sdf.getTimeZone();
                        t.setRawOffset(0);
                        sdf.setTimeZone(t);
                        Long startTime = System.currentTimeMillis();//用于计算从excel文件中读取数据耗时
                        
                        String fileName = "in.xlsx";
                        readExcel(fileName);// 读取Excel,xlsx后缀名的文件
                        
                        Long endTime = System.currentTimeMillis();
                        System.out.println("用时:" + sdf.format(new Date(endTime - startTime)));
                    } catch (Exception ex) {
                        System.out.println(ex.getMessage());
                        ex.printStackTrace();
                    }
                }
            });    
            
            JPanel bottomPanel=new JPanel();
            bottomPanel.setLayout(new BorderLayout());
            bottomPanel.add(exportButton, BorderLayout.NORTH);
            bottomPanel.add(readButton, BorderLayout.SOUTH);
            
            frame.getContentPane().add("Center", scroll);
            frame.getContentPane().add("South", bottomPanel);
    
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    
        @SuppressWarnings({ "resource"})
        public static void readExcel(String strPath) throws IOException {
            // 构造 XSSFWorkbook 对象,strPath 传入文件路径
            XSSFWorkbook xwb = new XSSFWorkbook(strPath);
            // 读取第一个表格内容
            XSSFSheet sheet = xwb.getSheetAt(0);//0表示第一个表格
            // 定义 row、cell
            XSSFRow row;        
            XSSFCell cell;    
            // 循环输出表格中的内容
            for (int i = sheet.getFirstRowNum(); i < sheet.getPhysicalNumberOfRows(); i++) {
                row = sheet.getRow(i);
                for (int j = row.getFirstCellNum(); j < row.getPhysicalNumberOfCells(); j++) {
                    String ret = "";    
                    cell=row.getCell(j);    
                    ret = getCellValueByCell(cell);        
                    System.out.print(ret + "	");
                }
                System.out.println("");
            }
        }
        
        //获取单元格各类型值,返回字符串类型
        public static String getCellValueByCell(Cell cell) {
            // 判断是否为null或空串
            if (cell == null || cell.toString().trim().equals("")) {
                return "";
            }
            
            String cellValue = "";
            CellType cellType = cell.getCellType();
            switch (cellType) {
            case NUMERIC:// 把枚举常量前的冗余类信息去掉编译即可通过
                short format = cell.getCellStyle().getDataFormat();
                if (DateUtil.isCellDateFormatted(cell)) {//注意:DateUtil.isCellDateFormatted()方法对“2019年1月18日"这种格式的日期,判断会出现问题,需要另行处理
                    SimpleDateFormat sdf = null;
                    // System.out.println("cell.getCellStyle().getDataFormat()="+cell.getCellStyle().getDataFormat());
                    if (format == 20 || format == 32) {
                        sdf = new SimpleDateFormat("HH:mm");
                    } else if (format == 14 || format == 31 || format == 57 || format == 58) {
                        // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
                        sdf = new SimpleDateFormat("yyyy-MM-dd");
                        double value = cell.getNumericCellValue();
                        Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
                        cellValue = sdf.format(date);
                    } else {// 日期
                        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    }
                    try {
                        cellValue = sdf.format(cell.getDateCellValue());// 日期
                    } catch (Exception e) {
                        try {
                            throw new Exception("exception on get date data !".concat(e.toString()));
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        }
                    } finally {
                        sdf = null;
                    }
                } else {
                    BigDecimal bd = new BigDecimal(cell.getNumericCellValue());
                    cellValue = bd.toPlainString();// 数值 这种用BigDecimal包装再获取plainString,可以防止获取到科学计数值
                }
                break;
            case STRING: // 字符串
                cellValue = cell.getStringCellValue();
                break;
            case BOOLEAN: // Boolean
                cellValue = cell.getBooleanCellValue() + "";
                break;
            case FORMULA: // 公式
            {
    //            cellValue = cell.getCellFormula();//读取单元格中的公式
                cellValue = String.valueOf(cell.getNumericCellValue());//读取单元格中的数值
            }
                break;
            case BLANK: // 空值
                cellValue = "";
                break;
            case ERROR: // 故障
                cellValue = "ERROR VALUE";
                break;
            default:
                cellValue = "UNKNOW VALUE";
                break;
            }
            return cellValue;
        }
        
        /**
         * 用户列表导出,生成Excel
         */
        private static void createExcel(TableModel model, String outFileFullPath) {
            XSSFWorkbook userListExcel = createUserListExcel(model);
            try {
                // 输出成文件
                FileOutputStream outputStream = new FileOutputStream(new File(outFileFullPath));
                userListExcel.write(outputStream);
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 创建excel
         */
        private static XSSFWorkbook createUserListExcel(TableModel model) {
            // 1.创建HSSFWorkbook,一个HSSFWorkbook对应一个Excel文件
            XSSFWorkbook wb = new XSSFWorkbook();
            // 2.在workbook中添加一个sheet,对应Excel文件中的sheet
            XSSFSheet sheet = wb.createSheet("sheet1");
            // 3.设置表头,即每个列的列名
            XSSFRow row = sheet.createRow(0);//创建第一行
            
            for (int i = 0; i < model.getColumnCount(); i++) {
                row.createCell(i).setCellValue(model.getColumnName(i));// 给列写入数据,创建单元格,将列名写入
            }
            
            // 写入正式数据
            for (int i = 1; i <= model.getRowCount(); i++) {// 先行索引。由于第一行已经被表格的标题占据了,所以昌数据索引从1开始
                row = sheet.createRow(i);//创建真正的行用于存放数据
                for (int j = 0; j < model.getColumnCount(); j++) {// 后列索引
                    row.createCell(j).setCellValue(model.getValueAt(i-1, j).toString());
                    sheet.autoSizeColumn(1, true);
                }
            }
            
            return wb;
        }
    
    }

    3、运行结果

    主界面:

    输出结果:

    输入结果:

    说明:

    上文中的in.xlsx和out.xlsx均在工程当前目录下,如下图所示:

    参考文献:

    1、http://www.zuidaima.com/code/file/2737946451706880.htm?dir=/2737946451706880.java

    2、JAVA实现数据库数据导入/导出到Excel(POI)

    3、java使用POI将数据导出放入Excel

    4、Excel导入时,日期格式的判断 isCellDateFormatted(Cell cell)不成功原因

    5、java通过poi读取excel中的日期类型数据或自定义类型日期

    6、poi读取Excel时日期为数字 的解决方法

  • 相关阅读:
    Jessica's Reading Problem POJ
    FatMouse and Cheese HDU
    How many ways HDU
    Humble Numbers HDU
    Doing Homework again
    Stacks of Flapjacks UVA
    Party Games UVA
    24. 两两交换链表中的节点
    面试题 03.04. 化栈为队
    999. 可以被一步捕获的棋子数
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/12507643.html
Copyright © 2011-2022 走看看