使用poi对Excel进行创建、读取、写入等操作

最近遇到一个项目,其中需要对Excel进行读取、写入、创建等操作,于是在网上查了资料使用了poi包来解析Excel,在此总结一下poi包的一些简单用法,以备以后使用,如有不对之处,欢迎各位指正。

这里提供一下使用poi所需要的jar包,有需要的朋友可以进行下载:poi-4.0.1所需jar包


一、读取Excel

public class ReadExcelTool {

    //总行数
    private int totalRows = 0;

    //总列数
    private int totalCells = 0;

    //错误信息
    private String errorInfo;

    //判断文件是否存在或是否是Excel格式
    public boolean validateExcel(String filePath){
        if (filePath == null || !(WDWUtil.isExcel2003(filePath) || WDWUtil.isExcel2007(filePath))){
            errorInfo = "文件不是Excel格式";
            return false;
        }
        File file = new File(filePath);
        if (file == null || !file.exists()){
            errorInfo = "文件不存在";
            return false;
        }
        return true;
    }

    //读取Excel文件
    public List readXls(String filePath) throws Exception{
        List dataList = new ArrayList();
        InputStream is = null;
        try{
            //验证文件是否合法
            if (!validateExcel(filePath)){
                System.out.println(errorInfo);
                return null;
            }
            //判断文件的类型
            //public static boolean isExcel2003(String filePath){
        return filePath.matches("^.+\\.(?i)(xls)$");
    }
            //public static boolean isExcel2007(String filePath){
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }
            boolean isExcel2003 = true;
            if (WDWUtil.isExcel2007(filePath)){
                isExcel2003 = false;
            }
            //调用方法读取Excel
            File file = new File(filePath);
            is = new FileInputStream(file);
            dataList = read(is,isExcel2003);
            is.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            if (is != null){
                try{
                    is.close();
                } catch (Exception ex){
                    is = null;
                    ex.printStackTrace();
                }
            }
        }
        return dataList;
    }

    //根据不同版本读取Excel文件
    public List read(InputStream inputStream,boolean isExcel2003){
        List dataList = null;
        try{
            //根据Excel文件版本创建Workbook的方式
            Workbook wb = null;
            if (isExcel2003){
                //文件后缀xls
                wb = new HSSFWorkbook(inputStream);
            }else{
                //文件后缀xlsx
                wb = new XSSFWorkbook(inputStream);
            }
            dataList = read(wb);
        }catch (IOException e){
            e.printStackTrace();
        }
        return dataList;
    }

    //解析Excel表格
    private List read(Workbook wb){
        List dataList = new ArrayList<>();
        //得到第一个sheet
        Sheet sheet = wb.getSheetAt(0);
        //得到Excel的行数
        this.totalRows = sheet.getPhysicalNumberOfRows();
        //得到Excel的列数
        if (this.totalRows >= 1 && sheet.getRow(0) != null){
            this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
        }
        //循环Excel的行
        for(int r=1;r

值得注意的是,在取单元格的值时,Excel单元格中不同格式的数据是对应不同的方法的,因为poi会检测数据的类型。如此处获取文本信息则使用getStringCellValue(),如果读取其他格式的数据则需要不同的方法:

1.数值类型使用getNumericCellValue()

2.布尔类型使用getBooleanCellValue()

3.公式使用getCellFormula()

此外还有一些其他的类型如空值、错误等。


二、创建Excel

如果我们需要生成的是一个有规律的Excel,那么使用poi来生成就非常方便;而如果是一个没有规律的Excel(某些地方需要合并单元格,某些地方需要加边框),那么建议使用第三种操作(写入Excel),越是复杂的Excel生成起来越麻烦。

//根据提供的Excel文件模板生成一个excel
    public static HSSFWorkbook BuildExcel(){
        //一个workbook对应一个excel,此处创建的是2003版本
        HSSFWorkbook wb = new HSSFWorkbook();

        //生成excel中可能用到的单元格样式
        //字体样式
        HSSFFont font1 = wb.createFont();           //仿宋_GB2312,14号字
        font1.setFontName("仿宋_GB2312");           //字体名称
        font1.setFontHeightInPoints((short)14);     //字体大小

        HSSFFont font2 = wb.createFont();          //宋体,18号字
        font2.setFontName("宋体");
        font2.setFontHeightInPoints((short)18);

        HSSFFont font3 = wb.createFont();          //方正仿宋,14号字
        font3.setFontName("方正仿宋");
        font3.setFontHeightInPoints((short)14);

        //单元格样式
        HSSFCellStyle style1 = wb.createCellStyle();            //垂直居中、水平左对齐,字体样式1
        style1.setFont(font1);                                  //注入字体
        style1.setVerticalAlignment(VerticalAlignment.CENTER);  //垂直居中
        style1.setAlignment(HorizontalAlignment.LEFT);          //水平左对齐

        HSSFCellStyle style2 = wb.createCellStyle();            //水平和垂直居中,字体样式2
        style2.setFont(font2);
        style2.setAlignment(HorizontalAlignment.CENTER);        //水平居中
        style2.setVerticalAlignment(VerticalAlignment.CENTER);

        HSSFCellStyle style9 = wb.createCellStyle();            //垂直顶端对齐、水平左对齐,字体样式3,带四周边框,自动换行
        style9.setFont(font3);
        style9.setVerticalAlignment(VerticalAlignment.TOP);
        style9.setAlignment(HorizontalAlignment.LEFT);
        style9.setBorderBottom(BorderStyle.THIN);               //边框宽度为1
        style9.setBorderTop(BorderStyle.THIN);
        style9.setBorderLeft(BorderStyle.THIN);
        style9.setBorderRight(BorderStyle.THIN);
        style9.setWrapText(true);                               //自动换行

        //生成一个sheet,对应excel中的sheet,参数为excel中sheet显示的名字
        HSSFSheet sheet = wb.createSheet("Sheet1");

        //设置每列的宽度,共有15列
        sheet.setColumnWidth(0,(int)(10.75*256*1.1));
        sheet.setColumnWidth(1,(int)(18.88*256*1.1));
        sheet.setColumnWidth(2,(int)(7.25*256*1.1));
        sheet.setColumnWidth(3,(int)(12.38*256*1.1));
        sheet.setColumnWidth(4,(int)(12.38*256*1.1));
        sheet.setColumnWidth(5,(int)(12.38*256*1.1));
        sheet.setColumnWidth(6,(int)(16.75*256*1.1));
        sheet.setColumnWidth(7,(int)(22.13*256*1.1));
        sheet.setColumnWidth(8,(int)(29.63*256*1.1));
        sheet.setColumnWidth(9,(int)(4.75*256*1.1));
        sheet.setColumnWidth(10,(int)(24.88*256*1.1));
        sheet.setColumnWidth(11,(int)(5.75*256*1.1));
        sheet.setColumnWidth(12,(int)(14.88*256*1.1));
        sheet.setColumnWidth(13,(int)(24.75*256*1.1));
        sheet.setColumnWidth(14,(int)(8*256*1.1));

        //单独设置每一行
        //第一行
        HSSFRow row1 = sheet.createRow(0);
        row1.setHeight((short)(20*29.25));                       //设定行高
        //创建每一行的每个单元格
        HSSFCell cell = row1.createCell(0);
        cell.setCellStyle(style1);
        cell.setCellValue("附1");

        //第二行
        HSSFRow row2 = sheet.createRow(1);
        row2.setHeight((short)(20*13.5));

        //第三行
        HSSFRow row3 = sheet.createRow(2);
        row3.setHeight((short)(20*31.5));
        sheet.addMergedRegion(new CellRangeAddress(2,2,0,14));  //单元格合并,参数(起始行、结束行、起始列、结束列)
        cell = row3.createCell(0);
        cell.setCellStyle(style2);

        return wb;
    }

从代码中可以看出,要创建一个Excel,首先要创建一个workbook,在workbook上创建sheet,在sheet中创建每一个单元格,并且设置其样式。

因为我使用的是WPS打开Excel,所以我的列宽显示的单位是字符,行高显示的单位是磅。假如给了一个模板,按照其来创建Excel,那么设定列宽的时候值就取col*256*1.1,col是模板中列的列宽,这样得到的结果会比原有宽度稍大;在设定行高的时候,值就取20*row,row是模板中行的行高,这样得到的结果与原有行高相同。

另外,在给合并单元格设置样式和填值得时候,只需要在这个合并单元格的左上角单元格设置即可,给个例子。

使用poi对Excel进行创建、读取、写入等操作_第1张图片

此处我合并了第4行至第7行,第3列至第5列的单元格,那么针对第四行第三列这个单元格设置样式和填值即可。但是这里有一个比较坑的地方,那就是如果想给这个合并单元格添加边框的话,就不能只针对这一个单元格,而是要将这个合并单元格外围的所有子单元格都设置好样式(带边框)。


三、写入Excel

其实写入Excel相当于前两种用法的结合,先读取Excel获得一个workbook,再对这个workbook进行各种操作。

public static HSSFWorkbook addCompanyMessageToExcel(HSSFWorkbook wb, Result re){
        Sheet sheet = wb.getSheet("Sheet1");

        Cell cell = sheet.getRow(4).getCell(2);
        cell.setCellValue(re.getBEI().getENTNAME());

        //循环对单元格进行调整
        for(int i=0;i

读取Excel获得workbook可以参见文章开头第一种用法。


如后续有更多poi的用法,将会持续更新,也欢迎各位进行指正和讨论。

你可能感兴趣的:(java)