zoukankan      html  css  js  c++  java
  • java操作Excel

    一.POI简介

    Jakarta POI 是apache的子项目,目标是处理ole2对象。它提供了一组操纵Windows文档的Java API

    目前比较成熟的是HSSF接口,处理MS Excel(97-2002)对象。它不象我们仅仅是用csv生成的没有格式的可以由Excel转换的东西,而是真正的Excel对象,你可以控制一些属性如sheet,cell等等。

    二.HSSF概况

    HSSF 是Horrible SpreadSheet Format的缩写,也即“讨厌的电子表格格式”。也许HSSF的名字有点滑稽,就本质而言它是一个非常严肃、正规的API。通过HSSF,你可以用纯Java代码来读取、写入、修改Excel文件。

    HSSF 为读取操作提供了两类API:usermodel和eventusermodel,即“用户模型”和“事件-用户模型”。前者很好理解,后者比较抽象,但操作效率要高得多。

    三.开始编码

    1 . 准备工作

    要求:JDK 1.4+POI开发包

    可以到 http://www.apache.org/dyn/closer.cgi/jakarta/poi/ 最新的POI工具包

    2 . EXCEL 结构

    HSSFWorkbook excell 文档对象介绍
    HSSFSheet excell的表单
    HSSFRow excell的行
    HSSFCell excell的格子单元
    HSSFFont excell字体
    HSSFName 名称
    HSSFDataFormat 日期格式
    在poi1.7中才有以下2项:
    HSSFHeader sheet头
    HSSFFooter sheet尾
    和这个样式
    HSSFCellStyle cell样式
    辅助操作包括
    HSSFDateUtil 日期
    HSSFPrintSetup 打印
    HSSFErrorConstants 错误信息表

    3 .具体用法实例 (采用 usermodel )

    如何读Excel

    读取Excel文件时,首先生成一个POIFSFileSystem对象,由POIFSFileSystem对象构造一个HSSFWorkbook,该HSSFWorkbook对象就代表了Excel文档。下面代码读取上面生成的Excel文件写入的消息字串:


    代码
    POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:/test.xls"));     
    HSSFWorkbook  wb = new HSSFWorkbook(fs);     
      } catch (IOException e) {     
      e.printStackTrace();     
      }     
      HSSFSheet sheet = wb.getSheetAt(0);     
      HSSFRow row = sheet.getRow(0);     
      HSSFCell cell = row.getCell((short) 0);     
      String msg = cell.getStringCellValue();   
    POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:/test.xls"));     
    HSSFWorkbook  wb = new HSSFWorkbook(fs);     
      } catch (IOException e) {     
      e.printStackTrace();     
      }     
      HSSFSheet sheet = wb.getSheetAt(0);     
      HSSFRow row = sheet.getRow(0);     
      HSSFCell cell = row.getCell((short) 0);     
      String msg = cell.getStringCellValue();   
    如何写excel,

    将excel的第一个表单第一行的第一个单元格的值写成“a test”。

    代码
    POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream("workbook.xls"));     
       
        HSSFWorkbook wb = new HSSFWorkbook(fs);     
       
        HSSFSheet sheet = wb.getSheetAt(0);     
       
        HSSFRow row = sheet.getRow(0);     
       
        HSSFCell cell = row.getCell((short)0);     
       
        cell.setCellValue("a test");     
       
        // Write the output to a file     
       
        FileOutputStream fileOut = new FileOutputStream("workbook.xls");     
       
        wb.write(fileOut);     
       
    fileOut.close();   
    4 . 可参考文档

    POI 主页:http://jakarta.apache.org/poi/

    初学者如何快速上手使用POI HSSF

    http://jakarta.apache.org/poi/hssf/quick-guide.html 。

    代码例子 http://blog.java-cn.com/user1/6749/archives/2005/18347.html

    里面有很多例子代码,可以很方便上手。

    POI的中级应该用
     

    1、遍历workbook
    代码
    // load源文件    
    POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(filePath));    
    HSSFWorkbook wb = new HSSFWorkbook(fs);    
    for (int i = 0; i < wb.getNumberOfSheets(); i++) {    
        HSSFSheet sheet = wb.getSheetAt(i);    
        for (int i = sheet.getFirstRowNum(); i < sheet.getLastRowNum(); i ++) {    
        HSSFRow row = sheet.getRow(i);    
                if (row != null) {    
            。。。操作}    
           }    
         }    
    // 目标文件    
    FileOutputStream fos = new FileOutputStream(objectPath);    
    //写文件    
    swb.write(fos);    
    fos.close();  
    2、得到列和单元格
    代码
    HSSFRow row = sheet.getRow(i);    
    HSSFCell cell = row.getCell((short) j);  
    3、设置sheet名称和单元格内容为中文
    代码
    wb.setSheetName(n, "中文",HSSFCell.ENCODING_UTF_16);        
    cell.setEncoding((short) 1);    
    cell.setCellValue("中文");  
    4、单元格内容未公式或数值,可以这样读写
    代码
    cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);    
    cell.getNumericCellValue() 

    5、设置列宽、行高
    代码
    sheet.setColumnWidth((short)column,(short)width);    
    row.setHeight((short)height); 

    6、添加区域,合并单元格
    代码
    Region region = new Region((short)rowFrom,(short)columnFrom,(short)rowTo,(short)columnTo);    
    sheet.addMergedRegion(region);    
    //得到所有区域    
    sheet.getNumMergedRegions()  
    7、常用方法
    根据单元格不同属性返回字符串数值
    代码
    public String getCellStringValue(HSSFCell cell) {    
            String cellValue = "";    
            switch (cell.getCellType()) {    
            case HSSFCell.CELL_TYPE_STRING:    
                cellValue = cell.getStringCellValue();    
                if(cellValue.trim().equals("")||cellValue.trim().length()<=0)    
                    cellValue=" ";    
                break;    
            case HSSFCell.CELL_TYPE_NUMERIC:    
                cellValue = String.valueOf(cell.getNumericCellValue());    
                break;    
            case HSSFCell.CELL_TYPE_FORMULA:    
                cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);    
                cellValue = String.valueOf(cell.getNumericCellValue());    
                break;    
            case HSSFCell.CELL_TYPE_BLANK:    
                cellValue=" ";    
                break;    
            case HSSFCell.CELL_TYPE_BOOLEAN:    
                break;    
            case HSSFCell.CELL_TYPE_ERROR:    
                break;    
            default:    
                break;    
            }    
            return cellValue;    
        } 


    8、常用单元格边框格式 
    虚线HSSFCellStyle.BORDER_DOTTED
    实线HSSFCellStyle.BORDER_THIN
    代码
    public static HSSFCellStyle getCellStyle(short type)    
        {       
           HSSFWorkbook wb = new HSSFWorkbook();    
           HSSFCellStyle style = wb.createCellStyle();    
           style.setBorderBottom(type);//下边框     
            style.setBorderLeft(type);//左边框     
            style.setBorderRight(type);//右边框     
            style.setBorderTop(type);//上边框     
           return style;    
        } 


    9、设置字体和内容位置

    代码
    HSSFFont f  = wb.createFont();    
    f.setFontHeightInPoints((short) 11);//字号    
    f.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);//加粗    
    style.setFont(f);    
    style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中    
    style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中    
    style.setRotation(short rotation);//单元格内容的旋转的角度    
    HSSFDataFormat df = wb.createDataFormat();    
    style1.setDataFormat(df.getFormat("0.00%"));//设置单元格数据格式    
    cell.setCellFormula(string);//给单元格设公式    
    style.setRotation(short rotation);//单元格内容的旋转的角度    
    cell.setCellStyle(style);  


    10、插入图片
    论坛里看到的

    代码
    //先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray    
          ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();    
          BufferedImage bufferImg = ImageIO.read(new File("ok.jpg"));    
          ImageIO.write(bufferImg,"jpg",byteArrayOut);    
    //读进一个excel模版    
    FileInputStream fos = new FileInputStream(filePathName+"/stencil.xlt");     
    fs = new POIFSFileSystem(fos);    
    //创建一个工作薄    
    HSSFWorkbook wb = new HSSFWorkbook(fs);    
    HSSFSheet sheet = wb.getSheetAt(0);    
    HSSFPatriarch patriarch = sheet.createDrawingPatriarch();    
    HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)10,10);         
    patriarch.createPicture(anchor , wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));  
    11、设置列自动换行

       HSSFCellStyle cellStyle =  workbook.createCellStyle();
       cellStyle.setWrapText(true);
       sheet.setDefaultColumnStyle((short)0, cellStyle);

        设置列的宽度

       sheet.setColumnWidth((short)0,(short)9000);

      sheet.setDefaultColumnStyle((short)0, cellStyle);

      与

      sheet.setDefaultColumnWidth((short)70);冲突

      只会换行 不会设置列宽

     
    单元格拷贝示例:

    package testpoi;

     
    import java.io.FileInputStream;

    import java.io.FileNotFoundException;

    import java.io.FileOutputStream;

    import java.io.IOException;

     
    import org.apache.poi.hssf.usermodel.HSSFCell;

    import org.apache.poi.hssf.usermodel.HSSFRow;

    import org.apache.poi.hssf.usermodel.HSSFSheet;

    import org.apache.poi.hssf.usermodel.HSSFWorkbook;

    import org.apache.poi.hssf.util.Region;

    import org.apache.poi.poifs.filesystem.POIFSFileSystem;

    /**

     * 将某SHEET页中的某几行复制到某SHEET页的某几行中。抱括被合并了的单元格。

     */

    public class RowCopy {
    /**

    * @param args

    * @throws IOException

    * @throws FileNotFoundException

    */
    @SuppressWarnings("deprecation")

    public static void main(String[] args) {

    try {

    POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(

    "d://exlsample.xls"));

    HSSFWorkbook wb = new HSSFWorkbook(fs);

     
    // source为源sheet 页,target为目标sheet页

    copyRows(wb, "source", "target", 5, 6, 20);

    FileOutputStream fileOut = new FileOutputStream("d://exlsample.xls");

    wb.write(fileOut);

    fileOut.flush();

    fileOut.close();

    System.out.println("Operation finished");

    } catch (Exception e) {

    e.printStackTrace();

    }

    }

     
    /**

    * @param wb HSSFWorkbook

    * @param pSourceSheetName 源sheet页名称

    * @param pTargetSheetName 目标sheet页名称

    * @param pStartRow 源sheet页中的起始行

    * @param pEndRow  源sheet页中的结束行

    * @param pPosition 目标sheet页中的开始行

    */

    public static void copyRows(HSSFWorkbook wb, String pSourceSheetName,

    String pTargetSheetName, int intStartRow, int intEndRow, int intPosition) {

    // EXECL中的行是从1开始的,而POI中是从0开始的,所以这里要减1.

    int pStartRow = intStartRow - 1;

    int pEndRow = intEndRow - 1;

    int pPosition = intPosition - 1;

    HSSFRow sourceRow = null;

    HSSFRow targetRow = null;

    HSSFCell sourceCell = null;

    HSSFCell targetCell = null;

    HSSFSheet sourceSheet = null;

    HSSFSheet targetSheet = null;

    Region region = null;

    int cType;

    int i;

    int j;

    int targetRowFrom;

    int targetRowTo;

     
    if ((pStartRow == -1) || (pEndRow == -1)) {

    return;

    }

    sourceSheet = wb.getSheet(pSourceSheetName);

    targetSheet = wb.getSheet(pTargetSheetName);

    System.out.println(sourceSheet.getNumMergedRegions());

    // 拷贝合并的单元格

    for (i = 0; i < sourceSheet.getNumMergedRegions(); i++) {

    region = sourceSheet.getMergedRegionAt(i);

    if ((region.getRowFrom() >= pStartRow)

    && (region.getRowTo() <= pEndRow)) {

    targetRowFrom = region.getRowFrom() - pStartRow + pPosition;

    targetRowTo = region.getRowTo() - pStartRow + pPosition;

    region.setRowFrom(targetRowFrom);

    region.setRowTo(targetRowTo);

    targetSheet.addMergedRegion(region);

    }

    }

    // 设置列宽

    for (i = pStartRow; i <= pEndRow; i++) {

    sourceRow = sourceSheet.getRow(i);

    if (sourceRow != null) {

    for (j = sourceRow.getLastCellNum(); j > sourceRow

    .getFirstCellNum(); j--) {

    targetSheet

    .setColumnWidth(j, sourceSheet.getColumnWidth(j));

    targetSheet.setColumnHidden(j, false);

    }

    break;

    }

    }

    // 拷贝行并填充数据

    for (; i <= pEndRow; i++) {

    sourceRow = sourceSheet.getRow(i);

    if (sourceRow == null) {

    continue;

    }

    targetRow = targetSheet.createRow(i - pStartRow + pPosition);

    targetRow.setHeight(sourceRow.getHeight());

    for (j = sourceRow.getFirstCellNum(); j < sourceRow

    .getPhysicalNumberOfCells(); j++) {

    sourceCell = sourceRow.getCell(j);

    if (sourceCell == null) {

    continue;

    }

    targetCell = targetRow.createCell(j);

    targetCell.setCellStyle(sourceCell.getCellStyle());

    cType = sourceCell.getCellType();

    targetCell.setCellType(cType);

    switch (cType) {

    case HSSFCell.CELL_TYPE_BOOLEAN:

    targetCell.setCellValue(sourceCell.getBooleanCellValue());

    System.out.println("--------TYPE_BOOLEAN:"

    + targetCell.getBooleanCellValue());

    break;

    case HSSFCell.CELL_TYPE_ERROR:

    targetCell

    .setCellErrorValue(sourceCell.getErrorCellValue());

    System.out.println("--------TYPE_ERROR:"

    + targetCell.getErrorCellValue());

    break;

    case HSSFCell.CELL_TYPE_FORMULA:

    // parseFormula这个函数的用途在后面说明

    targetCell.setCellFormula(parseFormula(sourceCell

    .getCellFormula()));

    System.out.println("--------TYPE_FORMULA:"

    + targetCell.getCellFormula());

    break;

    case HSSFCell.CELL_TYPE_NUMERIC:

    targetCell.setCellValue(sourceCell.getNumericCellValue());

    System.out.println("--------TYPE_NUMERIC:"

    + targetCell.getNumericCellValue());

    break;

    case HSSFCell.CELL_TYPE_STRING:

    targetCell

    .setCellValue(sourceCell.getRichStringCellValue());

    System.out.println("--------TYPE_STRING:" + i

    + targetCell.getRichStringCellValue());

    break;

    }

    }
    }
    }


    /**

    * POI对Excel公式的支持是相当好的,但是有一个问题,如果公式里面的函数不带参数,比如now()或today(),

    * 那么你通过getCellFormula()取出来的值就是now(ATTR(semiVolatile))和today(ATTR(semiVolatile)),

    * 这样的值写入Excel是会出错的,这也是我上面copyRow的函数在写入公式前要调用parseFormula的原因,

    * parseFormula这个函数的功能很简单,就是把ATTR(semiVolatile)删掉。

    * @param pPOIFormula

    * @return

    */

    private static String parseFormula(String pPOIFormula) {

    final String cstReplaceString = "ATTR(semiVolatile)"; //$NON-NLS-1$

    StringBuffer result = null;

    int index;


    result = new StringBuffer();

    index = pPOIFormula.indexOf(cstReplaceString);

    if (index >= 0) {

    result.append(pPOIFormula.substring(0, index));

    result.append(pPOIFormula.substring(index

    + cstReplaceString.length()));

    } else {

    result.append(pPOIFormula);

    }
    return result.toString();

    }
    }

    参考地址:http://blog.163.com/wangfc123/blog/static/15746801200962332631573/

                  

  • 相关阅读:
    linux系统mysql数据库安装步骤
    uwsgi 配置文件
    服务器重启后,docker无法启动
    标准库functools.wraps的使用方法
    闭包函数延迟绑定问题
    python的面向对象编程
    python中包的介绍与常用模块
    drf知识整理一
    Django知识整理四(choices参数,MTV与MVC模型,ajax介绍,ajax传json文件,ajax传文件,contentType前后端传输数据编码格式)
    DRF序列化组件
  • 原文地址:https://www.cnblogs.com/sungyouyu/p/3870181.html
Copyright © 2011-2022 走看看