2013年11月5日星期二

POI如何使用已有Excel作为模板二三事


原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://williamx.blog.51cto.com/3629295/735377
关于POI
POI是Apache的一个开源项目,起初的目标是允许用户使用java代码来对Excel进行操作,发展到今天POI本身支持的范围已经逐步扩展到对Microsoft Office主要产品,包括:Excel\Word\PPT\Visio的全面支持,目前稳定版本为3.7,开发版本为3.8。
应用场景
本文仅对项目中遇到的,使用已有Excel作为模板的场景来进行描述。
代码示例
public void demo(){
        try {
            // 先读取模板
            POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(
                    "c://demo_template.xls"));
           
            // 基于模板创建workbook
            HSSFWorkbook workbook = new HSSFWorkbook(fs);
            // 如果模板存在多页的话可以分别取到
            HSSFSheet sheet_1st = workbook.getSheetAt(0);
            HSSFSheet sheet_2nd = workbook.getSheetAt(1);
           
            // 第一页,第一行
            HSSFRow row = sheet_1st.getRow(0);
           
            // 取第一个单元格
            HSSFCell cell = row.getCell(0);
           
            // 获取单元格字符串值
            String cellValue = cell.getStringCellValue();
           
            // 设置单元格的值
            cell.setCellValue("demo");
           
            // 设置单元格的样式
            HSSFCellStyle cellStyle  =  workbook.createCellStyle();
            cell.setCellStyle(cellStyle);
           
            // 使用公式设置文档内超链接
            cell.setCellFormula(    "HYPERLINK(\"#内容!A1\", \"demo\")");
           
            // 使用HSSFHyperlink对象设置URL超链接
            HSSFHyperlink link = new HSSFHyperlin(HSSFHyperlink.LINK_URL);
            link.setAddress("http://www.163.com");      
            cell.setHyperlink(link);
           
            String path = "c://demo.xls";
            // 输出Excel
            FileOutputStream stream  =   new  FileOutputStream(path);
            workbook.write(stream);
           
            stream.flush();
            stream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
特别注意
          1. POI读取空行空格问题
 POI对空行或空格是不做处理的,如果Excel模板中第一行和第三行有数据的话,下面的代码:
HSSFRow row = sheet_1st.getRow(1);
取到的是第三行。如果想对第二行进行操作时,需要先创建一行:
HSSFRow row_2nd = sheet_2nd.createRow(1);
同样,单元格的规则也是一样,通过
row.getCell(index)方法未必是想要的单元格,在使用Excel模板时要特别注意。
2. CellStyle优化
同样的CellStyle在workbook中的存在缓存的,具有同样格式的单元格只要复用一份CellStyle即可,不要对每个单元格都重新创建CellStyle实例。