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时日期为数字 的解决方法

  • 相关阅读:
    Script:Generate A DDL Script For A Table
    如何在windows vista/2008/7中 安装Oracle OMS 即Grid Control
    Sqlserver2005迁移至Oracle系列之五:角色、用户、及权限
    Mysql:命令选项、配置选项、(全局、会话)系统变量、状态变量:SQL模式
    Mysql:命令选项、配置选项、(全局、会话)系统变量、状态变量:如何使用系统变量?
    Mysql:临时表、表变量
    Sqlserver2005迁移至Oracle系列之四:在Oracle中创建位或运算函数bitor
    flex 图片旋转
    基于模板和XML在BS结构应用中生成word文件
    操作图片文件写入word
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/12507643.html
Copyright © 2011-2022 走看看