poi使用整理总结

一、 POI简介
            Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
二、 HSSF概况

            HSSF 是Horrible SpreadSheet Format的缩写,通过HSSF,你可以用纯Java代码来读取、写入、修改Excel文件。HSSF 为读取操作提供了两类API:usermodel和eventusermodel,即“用户模型”和“事件-用户模型”。
三、 POI EXCEL文档结构类

            HSSFWorkbook excel文档对象

            HSSFSheet excel的sheet HSSFRow excel的行

            HSSFCell excel的单元格 HSSFFont excel字体

            HSSFName 名称 HSSFDataFormat 日期格式

            HSSFHeader sheet头

            HSSFFooter sheet尾

            HSSFCellStyle cell样式

            HSSFDateUtil 日期

            HSSFPrintSetup 打印

            HSSFErrorConstants 错误信息表
四、 EXCEL常用操作方法
  1、 得到Excel常用对象           
[c-sharp] view plaincopy

    POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:/test.xls"));   
    //得到Excel工作簿对象   
    HSSFWorkbook wb = new HSSFWorkbook(fs);  
    //得到Excel工作表对象   
    HSSFSheet sheet = wb.getSheetAt(0);   
    //得到Excel工作表的行   
    HSSFRow row = sheet.getRow(i);  
    //得到Excel工作表指定行的单元格   
    HSSFCell cell = row.getCell((short) j);  
    cellStyle = cell.getCellStyle();//得到单元格样式  

 2、建立Excel常用对象
[c-sharp] view plaincopy

    HSSFWorkbook wb = new HSSFWorkbook();//创建Excel工作簿对象  
    HSSFSheet sheet = wb.createSheet("new sheet");//创建Excel工作表对象    
    HSSFRow row = sheet.createRow((short)0); //创建Excel工作表的行  
    cellStyle = wb.createCellStyle();//创建单元格样式  
    row.createCell((short)0).setCellStyle(cellStyle); //创建Excel工作表指定行的单元格  
    row.createCell((short)0).setCellValue(1); //设置Excel工作表的值  

3、设置sheet名称和单元格内容
[c-sharp] view plaincopy

    wb.setSheetName(1, "第一张工作表",HSSFCell.ENCODING_UTF_16);          
    cell.setEncoding((short) 1);      
    cell.setCellValue("单元格内容");  

4、取得sheet的数目 
[c-sharp] view plaincopy

    wb.getNumberOfSheets()   

5、  根据index取得sheet对象
[c-sharp] view plaincopy

    HSSFSheet sheet = wb.getSheetAt(0);  

6、取得有效的行数
[c-sharp] view plaincopy

    int rowcount = sheet.getLastRowNum();  

7、取得一行的有效单元格个数
[c-sharp] view plaincopy

    row.getLastCellNum();    

8、单元格值类型读写

[c-sharp] view plaincopy

    cell.setCellType(HSSFCell.CELL_TYPE_STRING); //设置单元格为STRING类型  
    cell.getNumericCellValue();//读取为数值类型的单元格内容  

 

9、设置列宽、行高

[c-sharp] view plaincopy

    sheet.setColumnWidth((short)column,(short)width);      
    row.setHeight((short)height);    

 

10、添加区域,合并单元格

[c-sharp] view plaincopy

    Region region = new Region((short)rowFrom,(short)columnFrom,(short)rowTo  
    ,(short)columnTo);//合并从第rowFrom行columnFrom列  
    sheet.addMergedRegion(region);// 到rowTo行columnTo的区域     
    //得到所有区域      
    sheet.getNumMergedRegions()   

 

11、保存Excel文件

[c-sharp] view plaincopy

    FileOutputStream fileOut = new FileOutputStream(path);   
    wb.write(fileOut);   

 

12、根据单元格不同属性返回字符串数值

[c-sharp] view plaincopy

    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;      
        }     

 

13、常用单元格边框格式

[c-sharp] view plaincopy

    HSSFCellStyle style = wb.createCellStyle();      
    style.setBorderBottom(HSSFCellStyle.BORDER_DOTTED);//下边框       
    style.setBorderLeft(HSSFCellStyle.BORDER_DOTTED);//左边框       
    style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框       
    style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框    

 

14、设置字体和内容位置

[c-sharp] view plaincopy

    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);//单元格内容的旋转的角度   

 

15、插入图片

[c-sharp] view plaincopy

    //先把读进来的图片放到一个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));    

 

16、调整工作表位置

[c-sharp] view plaincopy

    HSSFWorkbook wb = new HSSFWorkbook();     
    HSSFSheet sheet = wb.createSheet("format sheet");     
    HSSFPrintSetup ps = sheet.getPrintSetup();     
    sheet.setAutobreaks(true);     
    ps.setFitHeight((short)1);     
    ps.setFitWidth((short)1);   

  

 

17、设置打印区域

[c-sharp] view plaincopy

    HSSFSheet sheet = wb.createSheet("Sheet1");     
    wb.setPrintArea(0, "$A$1:$C$2");    

 

18、标注脚注

[c-sharp] view plaincopy

    HSSFSheet sheet = wb.createSheet("format sheet");     
    HSSFFooter footer = sheet.getFooter()     
    footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() );   

 

19、在工作单中清空行数据,调整行位置

[c-sharp] view plaincopy

    HSSFWorkbook wb = new HSSFWorkbook();     
    HSSFSheet sheet = wb.createSheet("row sheet");     
    // Create various cells and rows for spreadsheet.     
    // Shift rows 6 - 11 on the spreadsheet to the top (rows 0 - 5)     
    sheet.shiftRows(5, 10, -5);    

 

20、选中指定的工作表

[c-sharp] view plaincopy

    HSSFSheet sheet = wb.createSheet("row sheet");     
    heet.setSelected(true);     

 

21、工作表的放大缩小

 
[c-sharp] view plaincopy

    HSSFSheet sheet1 = wb.createSheet("new sheet");     
    sheet1.setZoom(1,2);   // 50 percent magnification    

 

22、头注和脚注

[c-sharp] view plaincopy

    HSSFSheet sheet = wb.createSheet("new sheet");     
    HSSFHeader header = sheet.getHeader();     
    header.setCenter("Center Header");     
    header.setLeft("Left Header");     
    header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") +     
    HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16");  

 

23、自定义颜色

[c-sharp] view plaincopy

    HSSFCellStyle style = wb.createCellStyle();     
    style.setFillForegroundColor(HSSFColor.LIME.index);     
    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);     
    HSSFFont font = wb.createFont();     
    font.setColor(HSSFColor.RED.index);     
    style.setFont(font);     
    cell.setCellStyle(style);     

24、填充和颜色设置

[c-sharp] view plaincopy

    HSSFCellStyle style = wb.createCellStyle();     
    style.setFillBackgroundColor(HSSFColor.AQUA.index);     
    style.setFillPattern(HSSFCellStyle.BIG_SPOTS);     
    HSSFCell cell = row.createCell((short) 1);     
    cell.setCellValue("X");     
    style = wb.createCellStyle();     
    style.setFillForegroundColor(HSSFColor.ORANGE.index);     
    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);     
    cell.setCellStyle(style);   

25、强行刷新单元格公式

[c-sharp] view plaincopy

    HSSFFormulaEvaluator eval=new HSSFFormulaEvaluator((HSSFWorkbook) wb);    
    private static void updateFormula(Workbook wb,Sheet s,int row){     
            Row r=s.getRow(row);     
            Cell c=null;     
            FormulaEcaluator eval=null;     
            if(wb instanceof HSSFWorkbook)     
                eval=new HSSFFormulaEvaluator((HSSFWorkbook) wb);     
            else if(wb instanceof XSSFWorkbook)     
                eval=new XSSFFormulaEvaluator((XSSFWorkbook) wb);     
            for(int i=r.getFirstCellNum();i                 c=r.getCell(i);     
                if(c.getCellType()==Cell.CELL_TYPE_FORMULA)     
                    eval.evaluateFormulaCell(c);     
            }     
        }    

说明:FormulaEvaluator提供了evaluateFormulaCell(Cell cell)方法,计算公式保存结果,但不改变公式。而evaluateInCell(Cell cell) 方法是计算公式,并将原公式替换为计算结果,也就是说该单元格的类型不在是Cell.CELL_TYPE_FORMULA而是Cell.CELL_TYPE_NUMBERIC。HSSFFormulaEvaluator提供了静态方法evaluateAllFormu

laCells(HSSFWorkbook wb) ,计算一个Excel文件的所有公式,用起来很方便。

1. HSSFWorkbook类(创建excel表)

首先从Workbook开始我们的POI编程之旅。要生成一个Workbook,需要用到HSSFWorkbook类文件,类定义如下:

  • java.lang.Object
  • org.apache.poi.hssf.usermodel.HSSFWorkbook
  • public class HSSFWorkbook extends java.lang.Object

它有五个构造方法:

构建器

HSSFWorkbook()
Creates new HSSFWorkbook from scratch (start here!)

HSSFWorkbook(java.io.InputStream s)

HSSFWorkbook(java.io.InputStream s, boolean preserveNodes)
Companion to HSSFWorkbook(POIFSFileSystem), this constructs the POI filesystem around your inputstream.

HSSFWorkbook(POIFSFileSystem fs)

HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes)
given a POI POIFSFileSystem object, read in its Workbook and populate the high and low level models.

我们用第一个构建器来生成一个Workbook

HSSFWorkbook

public HSSFWorkbook()

Creates new HSSFWorkbook from scratch (start here!)

使用方法如下:

HSSFWorkbook workbook = new HSSFWorkbook();

接下来再来对生成的Workbook进行保存操作,保存操作用「HSSFWorkbook」类的「write」方法:

write

public void write(java.io.OutputStream stream) throws

java.io.IOException

 

Method write - write out this workbook to an Outputstream.

Constructs a new POI POIFSFileSystem, passes in the workbook

binary representation and writes it out.

 

Parameters:

  stream - - the java OutputStream you wish to write the XLS to

Throws:

  java.io.IOException - if anything can't be written.

参数是作为保存对象的输出流对象「OutputStream」。

 

示例程序

可以自己实际做一下啊。

import java.io.*;

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();//创建一个空白的workbook

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);//调用HSSFWorkbook类的write方法写入到输出流

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

运行刚才的示例程序来生成一个Excel文件吧。

==========================================异常华丽的分割线=============================================================

2. POIFSFileSystem类(读取excel表格)

这次我们用POI打开一个已经存在的Workbook。因为没有现成的方法,所以只能再次利用HSSFWorkbook构造方法

HSSFWorkbook

public HSSFWorkbook(POIFSFileSystem fs) throws java.io.IOException

--

这个构建器虽然没什么说明,但可以看出它的参数是一个「POIFSFileSystem」这样的一个类对象。那我们再来看看「POIFSFileSystem」类定义。

POIFSFileSystem类定义

「POIFSFileSystem」类对象可以把Excel文件作为数据流来进行传入传出。

  • java.lang.Object
  • org.apache.poi.poifs.filesystem.POIFSFileSystem
  • public class POIFSFileSystem extends java.lang.Object implements POIFSViewable

「POIFSFileSystem」类有两个构建器

构建器

POIFSFileSystem()
Constructor, intended for writing

POIFSFileSystem(java.io.InputStream stream)
Create a POIFSFileSystem from an InputStream

读取文件时使用第二个构建器。

POIFSFileSystem

public POIFSFileSystem(java.io.InputStream stream) throws

java.io.IOException

Create a POIFSFileSystem from an InputStream

 

Parameters:

  stream - the InputStream from which to read the data

Throws:

  java.io.IOException - on errors reading, or on invalid data

参数设定为读入Excel文件的流对象「InputStream」。使用方法如下。

FileInputStream in = new FileInputStream("sample.xls");//文件输入流

POIFSFileSystem fs = new POIFSFileSystem(in);//构建poifsfileSystem对象,根据输入流

HSSFWorkbook wb = new HSSFWorkbook(fs);

通过POIFSFileSystem读取Excel文件

下面就实际做一下如何读取Excel文件。

import java.io.*;

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample1.xls");//将excel文件转为输入流

      POIFSFileSystem fs = new POIFSFileSystem(in);//构建POIFSFileSystem类对象,用输入流构建

      workbook = new HSSFWorkbook(fs);//创建个workbook,根据POIFSFileSystem对象

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample2.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

这个示例程序的作用是读取「sample1.xls」文件后再把它作为「sample2.xls」保存。
「sample1.xls」文件如下。

uploading.4e448015.gif正在上传…重新上传取消

实行之后,会生成一模一样的文件「sample2.xls」。
打开如下。

uploading.4e448015.gif正在上传…重新上传取消

==========================================异常华丽的分割线=============================================================

3. 关于Sheet

HSSFSheet类定义

用POI来作成一个Sheet,可以用「HSSFSheet」类,它的类定义如下。

  • java.lang.Object
  • org.apache.poi.hssf.usermodel.HSSFSheet
  • public class HSSFSheet extends java.lang.Object

它有两个构造方法。

构建器

protected HSSFSheet(Workbook book)
Creates new HSSFSheet – called by HSSFWorkbook to create a sheet from scratch.

protected HSSFSheet(Workbook book, Sheet sheet)
Creates an HSSFSheet representing the given Sheet object.

虽然有两个构建器,但都是protected的,所以要新建Sheet,只能通过Workbook。

新建Sheet

在Workbook里新建Sheet时,还是使用「HSSFWorkbook」类的「createSheet」的方法,详细可以参照「在Workbook里创建Sheet」。
使用方法如下。

HSSFWorkbook workbook = new HSSFWorkbook();//创建个空白的workbook

HSSFSheet sheet = workbook.createSheet();//创建个空白的sheet

读取现有的Sheet

对于在Workbook已经存在的Sheet来说,可以用「HSSFWorkbook」类的「getSheet」方法来读取。

getSheet

public HSSFSheet getSheet(java.lang.String name)

Get sheet with the given name

 

Parameters:

  name - of the sheet

Returns:

  HSSFSheet with the name provided or null if it does not exist

(java.lang.String name)参数为Sheet名称。
使用方法如下。

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFSheet sheet = workbook.getSheet("sheet1")//读取名称为sheet1的sheet

不用Sheet名而用Sheet的序列号来取得Sheet的话,可以用「HSSFWorkbook」类的「getSheetAt」方法。

getSheetAt

public HSSFSheet getSheetAt(int index)

Get the HSSFSheet object at the given index.

 

Parameters:

  index - of the sheet number (0-based physical & logical)

Returns:

  HSSFSheet at the provided index

(int index)参数为sheet的序号

使用方法如下。

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFSheet sheet = workbook.getSheetAt(1);//读取序号为1的sheet(第二张sheet)

=================

Workbook创建Sheet

要在Workbook里创建一个Sheet,可以使用「HSSFWorkbook」类的「createSheet」方法。

createSheet

public HSSFSheet createSheet()

create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and

returns the high level representation. Use this to create new sheets.

 

Returns:

  HSSFSheet representing the new sheet.

还有一个名称相同的「createSheet」方法,但可以指定Sheet名。

createSheet

public HSSFSheet createSheet(java.lang.String sheetname)

create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and

returns the high level representation. Use this to create new sheets.

 

Parameters:

  sheetname - sheetname to set for the sheet.

Returns:

  HSSFSheet representing the new sheet.

创建的Sheet作为「HSSFSheet」类对象返回。

示例程序

import java.io.*;

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

 

    workbook.createSheet();//创建workbook的sheet

    workbook.createSheet();

    workbook.createSheet("test");

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

上面的示例程序执行后,会生成下面的「sample1.xls」文件。

 

如果没有设定Sheet名,会从0开始默认设定为Sheet0,Sheet1等,设定为test的话,则可以创建test这样的Sheet。

===================================

Workbook复制Sheet

要复制Workbook里现有的Sheet来创建新的Sheet,可以使用「HSSFWorkbook」类的「cloneSheet」方法。

cloneSheet

public HSSFSheet cloneSheet(int sheetNum)

create an HSSFSheet from an existing sheet in the HSSFWorkbook.

 

Returns:

  HSSFSheet representing the cloned sheet.

指定要复制的Sheet序列号。

示例程序

再一次动手来做做吧。复制前Workbook如下。

 

 

import java.io.*;

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    workbook.cloneSheet(0);

    workbook.cloneSheet(1);

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

执行后打开「sample1.xls」文件看看。

 

可以看出,两个Sheet被成功复制。被复制的Sheet名格式是「原Sheet名(序列号)」。顺便一提的是,如果你手动在Excel里进行复制的话,被复制的Sheet名的格式是「原Sheet名 (序列号)」。也就是原Sheet名和(序列号)之间有一个半角空格。

=============

Workbook删除Sheet

要从Workbook里删除Sheet,可以使用「HSSFWorkbook」类的方法「removeSheetAt」。

removeSheetAt

public void removeSheetAt(int index)

removes sheet at the given index

 

Parameters:

  index - of the sheet (0-based)

(int index)指定要删除Sheet的序列号。
如果不知道序列号的话,也可以通过「HSSFWorkbook」类的方法「getSheetIndex」,设定Sheet名来取得序列号。

getSheetIndex

public int getSheetIndex(java.lang.String name)

Returns the index of the sheet by his name

 

Parameters:

  name - the sheet name

Returns:

  index of the sheet (0 based)

(java.lang.String name)参数请指定要删除的Sheet名。

示例程序

生成一个Workbook,再在其中创建三个Sheet,最后再把名为「Sheet1」的Sheet删除。

import java.io.*;

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

 

    workbook.createSheet();

    workbook.createSheet();

    workbook.createSheet();

 

    workbook.removeSheetAt(workbook.getSheetIndex("Sheet1"));

 

    System.out.println("Sheet0 = " + workbook.getSheetIndex("Sheet0"));

    System.out.println("Sheet2 = " + workbook.getSheetIndex("Sheet2"));

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

示例程序执行后,会生成「sample1.xls」这样的文件,打开来看看先。

 

从图中可以看出,Sheet1被删除了,那么这时候序列号又是怎么样的呢?你还是可以通过「HSSFWorkbook」类的方法「getSheetIndex」,设定Sheet名来取得序列号看看。

Sheet0 = 0

Sheet2 = 1

我们发现中间的Sheet被删除后,后面的Sheet序列号会往前移一个,总之会维持从0开始的整数顺序。

============

改变sheet的名称

要改变现有Sheet或刚新建Sheet的名称,可以用「HSSFWorkbook」类的「setSheetName」方法。

setSheetName

public void setSheetName(int sheet, java.lang.String name)

set the sheet name. Will throw IllegalArgumentException if the name

is greater than 31 chars or contains /\?*[]

 

Parameters:

  sheet - number (0 based)

参数:(int sheet)指定要改变的Sheet的序列号。参数(java.lang.String  name)为要改变的名称,设置名称时,最大长度是31个文字,还有「/\?*[]」这样的字符不能使用。
指定汉字Sheet名时,用第二个方法。

setSheetName

public void setSheetName(int sheet, java.lang.String name,

                                   short encoding)

--

「encoding」的参数在「HSSFWorkbook」类里被定义成下面两种。

static byte ENCODING_COMPRESSED_UNICODE

static byte ENCODING_UTF_16     ---------------设置中文用

 

参数(int sheet, java.lang.String name,short encoding)

int sheet     sheet号

java.lang.String name     改变的名字

short encoding      设定汉字时(包括日语),「encoding」的参数应该传入「HSSFWorkbook.ENCODING_UTF_16」。

示例程序

亲自动手做一做吧。

import java.io.*;

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

 

    workbook.createSheet();

    workbook.createSheet();

 

    workbook.setSheetName(0, "test");//更改sheet0的名字为test

    workbook.setSheetName(1, "测试", HSSFWorkbook.ENCODING_UTF_16);//更改sheet1的名字为“测试”设置为utf-16

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

程序执行后,打开「sample1.xls」文件来看看。

 

可以看出,汉字Sheet名被正常设好了。
使用「createSheet」方法创建新的Sheet时,不能进行encoding设定。所以要设置汉字Sheet名时,只能先新建一个Sheet,然后再对该Sheet进行改名操作。

=====================

设定列宽度

如果想在工作表里指定列宽度的话,可以使用「HSSFSheet」类的「setColumnWidth」方法。

setColumnWidth
public void setColumnWidth(short column, short width)
set the width (in units of 1/256th of a character width) 
 
Parameters:
  column - - the column to set (0-based)
  width - - the width in units of 1/256th of a character width

(short column)指定列的序列号, (short width)指定列的宽度。宽度如果指定1的话,那就是一个文字的1/256(也就是说一个文字占256的宽度),4个文字的宽度是1024。

另外,要取得列宽度可以使用「HSSFSheet」类的「getColumnWidth」方法。

getColumnWidth
public short getColumnWidth(short column)
get the width (in units of 1/256th of a character width ) 
 
Parameters:
  column - - the column to set (0-based)
Returns:
  width - the width in units of 1/256th of a character width

(short column)指定列的序列号

示例程序

自己动手做一下吧。仍然按照下图准备一个Excel文件,取得从第0列到第2列的列宽、然后把第2列的列宽指定给第0列和第1列。

 

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    short[] width = new short[3];
 
    for (int i = 0 ; i < 3 ; i++){
      width[i] = sheet.getColumnWidth((short)i);
      System.out.println(i + "列宽度:" + width[i]);
    }//循环获取0,1,2的宽度
   //将第二列的宽度赋给第0,1列
    sheet.setColumnWidth((short)0, width[2]);
    sheet.setColumnWidth((short)1, width[2]);
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample2.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}

打开新生成的Excel文件看看。

0列宽度:1865
1列宽度:3986
2列宽度:2048

 

一个Excel文件新生成时,有自己默认的列宽度,当然我们也可以用POI来指定默认的列宽度。

指定默认的列宽度

指定默认的列宽度用「HSSFSheet」类的「setDefaultColumnWidth」方法。

setDefaultColumnWidth
public void setDefaultColumnWidth(short width)
set the default column width for the sheet (if the columns do not define
their own width) in characters 
 
Parameters:
  width - default column width

(short width)参数,这里要注意的就是,和刚才的方法不一样,这里的列宽度单位是1个文字,而不是刚才的一个文字的1/256。

要取得原来的默认列宽度,使用「getDefaultColumnWidth」方法。

getDefaultColumnWidth
public short getDefaultColumnWidth()
get the default column width for the sheet (if the columns do not define
their own width) in characters 
 
Returns:
  default column width

这里的列宽度单位也是一个文字

示例程序

动手做做看吧。

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
 
public class POISample{
  public static void main(String[] args){
    HSSFWorkbook workbook = new HSSFWorkbook();
    HSSFSheet sheet = workbook.createSheet();
 
    sheet.setDefaultColumnWidth((short)5);//将默认的列宽设为5个文字大小
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample2.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}

新生成的Excel文件打开来看看吧。

 

=================

调整工作表Sheet的显示比例

有时我们可能会手动去调整工作表Sheet的显示比例,用POI同样也能做到这一点。这时我们可以使用「HSSFSheet」类的「setZoom」方法。

setZoom
public void setZoom(int numerator, int denominator)
Sets the zoom magnication for the sheet. The zoom is expressed as a
fraction. For example to express a zoom of 75% use 3 for the
numerator and 4 for the denominator. 
 
Parameters:
  numerator - The numerator for the zoom magnification.
  denominator - The denominator for the zoom magnification.

(int numerator, int denominator)参数,这样就可以指定显示比例了,指定方法是用”numerator”÷”denominator”,比方说,「setZoom(2, 1)」就是设定为200%的比例,「setZoom(3, 4)」就是设定为75%的比例。

示例程序

动手做一下吧。

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);//取得序号为0的sheet 
    sheet.setZoom(2, 1);//改变sheet的显示比例为200%
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample2.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}

新生成的Excel文件如下图所示。

 

==========

合并单元格

现在再看看如果将指定的单元格进行合并操作。用POI进行合并操作,使用「HSSFSheet」类的「addMergedRegion」方法。

addMergedRegion

public int addMergedRegion(Region region)

adds a merged region of cells (hence those cells form one)

 

Parameters:

  region - (rowfrom/colfrom-rowto/colto) to merge

Returns:

  index of this region

参数(Region region),合并范围必须使用「Region」类来指定,关于「Region」类的介绍如下。

「Region」类关系图

  • java.lang.Object
  • org.apache.poi.hssf.util.Region
  • public class Region extends java.lang.Object implements java.lang.Comparable

「Region」类的构造方法

Region

public Region(int rowFrom, short colFrom, int rowTo, short colTo)// rowFrom起始行号, colFrom起始列号,rowTo结束行号,colTo结束列号

--

指定范围时,从左上的单元格到右下的单元格指定,比方像下面这样。

Region(1, (short)1, 2, (short)3)

示例程序

动手做做看,还是使用原来的Excel文件。

 

把上图选中的单元格进行合并操作时,看下面的程序。

import java.io.*;

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    HSSFSheet sheet = workbook.getSheetAt(0);

 

    sheet.addMergedRegion(new Region(1, (short)1, 2, (short)3));//从第2行第2列开始并到第3行,第4列

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample2.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

把刚作成的新的Excel文件打开看看吧

 

 

==========================================异常华丽的分割线=============================================================

4.关于SHEET中的行

HSSFRow类定义

用POI在工作表里作成一个行,可以用「HSSFRow」类,它的类定义如下。

  • java.lang.Object
  • org.apache.poi.hssf.usermodel.HSSFRow
  • public class HSSFRow extends java.lang.Object implements java.lang.Comparable

它的构造方法有三个。

构造方法

protected HSSFRow()

protected HSSFRow(Workbook book, Sheet sheet, int rowNum)
Creates new HSSFRow from scratch.

protected HSSFRow(Workbook book, Sheet sheet, RowRecord record)
Creates an HSSFRow from a low level RowRecord object.

虽然有三个,但每一个都是protected的,所以不能直接使用它的构造方法,而是用Sheet对象来创建行。

创建行

在工作表里创建行,使用「HSSFSheet」类的「createRow」方法,前面也讲过,你可以参照一下『Sheet里行的创建』。

使用方法如下:

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFSheet sheet = workbook.createSheet();

HSSFRow row = sheet.createRow(0);

取得已经存在的行

在工作表里取得行,使用「HSSFSheet」类的「getRow」方法,详细内容你可以参照一下『Sheet里行的读取』。

使用方法如下:

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFSheet sheet = workbook.createSheet();

HSSFRow row = sheet.getRow(0);

=============

A.获取行的状态

我们还可以用POI获取当前工作表的行的一些状态,比如获得第一行的序列号,使用「HSSFSheet」类的「getFirstRowNum」方法。

getFirstRowNum
public int getFirstRowNum()
gets the first row on the sheet 
 
Returns:
  the number of the first logical row on the sheet

还有,获得最后一行的序列号,使用「HSSFSheet」类的「getLastRowNum」方法。

getLastRowNum
public int getLastRowNum()
gets the last row on the sheet 
 
Returns:
  last row contained n this sheet.

还可以获得实际存在的行的总数,使用「HSSFSheet」类的「getPhysicalNumberOfRows」方法。

getPhysicalNumberOfRows
public int getPhysicalNumberOfRows()
Returns the number of phsyically defined rows (NOT the number of rows
in the sheet)

示例程序

自己动手做做吧。

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
 
public class POISample{
  public static void main(String[] args){
    HSSFWorkbook workbook = new HSSFWorkbook();
    HSSFSheet sheet = workbook.createSheet();
 
    System.out.println("创建行之前的状态:");
    System.out.println("First:" + sheet.getFirstRowNum());//sheet.getFirstRowNum()获取sheet的第一行行号
    System.out.println("Last:" + sheet.getLastRowNum());//getLastRowNum()获取sheet的最后行行号
    System.out.println("Total:" + sheet.getPhysicalNumberOfRows() + "\n");// getPhysicalNumberOfRows()获取sheet的行总数
 
    sheet.createRow(1);
 
    System.out.println("创建第一行后的状态:");
    System.out.println("First:" + sheet.getFirstRowNum());
    System.out.println("Last:" + sheet.getLastRowNum());
    System.out.println("Total:" + sheet.getPhysicalNumberOfRows() + "\n");
 
    sheet.createRow(3);
 
    System.out.println("创建第三行后的状态:");
    System.out.println("First:" + sheet.getFirstRowNum());
    System.out.println("Last:" + sheet.getLastRowNum());
    System.out.println("Total:" + sheet.getPhysicalNumberOfRows());
  }
}

用上面的代码实行看看。

创建行之前的状态:
First:0
Last:0
Total:0
 
创建第一行后的状态:
First:0
Last:1
Total:1
 
创建第三行后的状态:
First:0
Last:3
Total:2
getPhysicalNumberOfRows() 取得是创建的总行数,即存在的行数

==================

B.行的创建

之前仅仅新建了Sheet,虽然可以看到新建的Sheet里有无数的单元格,但还不能直接往这些单元格设值。要想往这些单元格里设值,你还必须创建行。
因此,再来看看行创建的方法。
在Sheet里创建行,使用「HSSFSheet」类的「createRow」方法。

createRow

public HSSFRow createRow(int rownum)

Create a new row within the sheet and return the high

level representation

 

Parameters:

  rownum - row number

Returns:

  High level HSSFRow object representing a row in the sheet

(int rownum)创建指定行号的行。行号是从0开始的整数,最大是65535,可以支持65536行。创建行所返回的值是「HSSFRow」类对象,关于「HSSFRow」类定义的说明,以后再详细说。
创建方法很多,要说详细挺复杂。比方说,即使第一行(行号为0)和第二行不创建,也能直接创建第三行。

示例程序

亲自动手做一下吧。

import java.io.*;

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();//创建个空白的workbook

 

    HSSFSheet sheet = workbook.createSheet();//创建个空白的sheet

 

    HSSFRow row = sheet.createRow(2);//创建行号为2的行,excel中的第三行

 

    HSSFCell cell = row.createCell((short)0);//创建上面行的第一个单元格

    cell.setCellValue("test");//将test写入单元格

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

在上面的程序里,生成一个Sheet,然后单独创建了第三行(行号为2),接着又创建了一个单元格,最后给这个单元格设了值。执行后,打开「sample.xls」文件看看。

 

可以看到,在第三行第一列,值已经被设定好了。

================

C.行的读取

要取得Sheet里的某一行,可以使用「HSSFSheet」类的「getRow」方法。

getRow

public HSSFRow getRow(int rownum)

Returns the logical row (not physical) 0-based. If you ask for a row

that is not defined you get a null. This is to say row 4 represents

the fifth row on a sheet.

 

Parameters:

  rownum - row to get

Returns:

  HSSFRow representing the rownumber or null if its not defined on the

    sheet

利用行号取得指定的行。如果行不存在,则返回NULL。

 

示例程序

动手做做看。

import java.io.*;

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

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

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

 

    HSSFSheet sheet = workbook.createSheet();

 

    HSSFRow row = sheet.createRow(1);

 

    for (int i = 0 ; i < 3 ; i++){

      HSSFRow r = sheet.getRow(i);

      if (r  == null){

        System.out.println("第" + i + "行不存在。");

      }else{

        System.out.println("第" + i + "行取得成功。");

      }

    }

  }

}

上面的程序里,先创建一个Sheet,然后创建第二行(行号为1)。最后读取第一行到第三行的三行。结果如下。

第0行不存在。

第1行取得成功。

第2行不存在。

这和予想的一样。

读取有值的行

按照下图准备一个Excel文件。

 

import java.io.*;

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    HSSFSheet sheet = workbook.getSheetAt(0);//读取序号为0的sheet

 

    for (int i = 0 ; i < 3 ; i++){

      HSSFRow r = sheet.getRow(i);

      if (r  == null){

        System.out.println("第" + i + "行不存在。");

      }else{

        System.out.println("第" + i + "行取得成功。");

      }

    }

  }

}

结果如下。

第0行取得成功。

第1行取得成功。

第2行不存在。

从上面的例子可以看出,如果当前行有值的话,那么读取这一行时肯定存在。

从取得的行里获取单元格的值。

这一次从已经取得的行里获取单元格的值。仍然使用刚才的Excel文件。用getRow方法先取得行对象,再从单元格里获取值。

import java.io.*;

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    HSSFSheet sheet = workbook.getSheetAt(0);//读取序号为0的sheet

 

    HSSFRow row = sheet.getRow(1);//取得sheet中第二行(行号1)

 

    HSSFCell cell = row.getCell((short)1);//取得第二行,第二格(单元格号1)

    System.out.println(cell.getStringCellValue());//cell.getStringCellValue()取值

  }

}

结果如下。

sample

可以看出,把第二行第二列的值取出来了。

===================

在现有的行上创建行(貌似没什么用啊)

最后,再来试试看,在现有的行上,用「createRow」方法创建一行看看会是什么结果。还是使用刚才的Excel文件,在第二行上创建一行,再把值取出来。

import java.io.*;

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    HSSFSheet sheet = workbook.getSheetAt(0);//取得0sheet

 

    HSSFRow row = sheet.createRow(1);//在已经有第二行的情况下再建第二行

 

    HSSFCell cell = row.getCell((short)1);//取得新建第二行的值

 

    System.out.println(cell.getStringCellValue());

  }

}

结果如下。

Exception in thread "main" java.lang.NullPointerException

        at POISample.main(POISample.java:35)

发生了空指针异常。本来对于已经存在的行用「createRow」方法进行创建行操作,可能你会以为会复制原来的行,但事实并非如此。
让我们在原来程序的基础上再稍作一些变化,已经存在的行用「createRow」方法进行创建行操作后,再在该行的空白单元格设上值,保存为新的文件。

import java.io.*;

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    HSSFSheet sheet = workbook.getSheetAt(0);

 

    HSSFRow row = sheet.createRow(1);

 

    HSSFCell cell = row.createCell((short)3);

    cell.setCellValue("news");

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample2.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

执行上面程序后,打开新的Excel文件如下。

 

对于已经存在的行再用「createRow」方法执行的话,那从原来行里有值的单元格取值时会发生空指针异常。但如果新创建一个单元格再设值的话,那之前单元格的值也会被保留下来。虽然是猜测,不过大家可以自己亲自动手来验证一下。

=======================

D.移动行

如果要移动某一行的话,可以使用「HSSFSheet」类的「shiftRows」方法。

shiftRows
public void shiftRows(int startRow, int endRow, int n)
Shifts rows between startRow and endRow n number of rows. If you use
a negative number, it will shift rows up. Code ensures that rows don't
wrap around. Calls shiftRows(startRow, endRow, n, false, false); 
 
Additionally shifts merged regions that are completely defined in
these rows (ie. merged 2 cells on a row to be shifted). 
 
Parameters:
  startRow - the row to start shifting
  endRow - the row to end shifting
   n - the number of rows to shift

int startRow, int endRow:指定要移动的行的范围从「startRow」行到「endRow」行。

int n:「n」如果是正数就往下移动的行数,如果为负,就往上移动。

示例程序

按下图准备一个Excel文件。

 

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    sheet.shiftRows(1, 2, 2);//第二行和第三行向下移动两行
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample2.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}

打开新建的Sample2.xls文件看看。

 

从上图可以看出,第二行和第三行的内容已经移动到第四行和第五行,并覆盖原第四行和第五行的内容。但第二行到第五行的行高却维持原样没有变化。
再来看看有没有办法可以既移动内容,又可以移动行高呢?从帮助文档里可以看出,对于「shiftRows」方法,还有另外一种用法。

shiftRows
public void shiftRows(int startRow, int endRow, int n,
              boolean copyRowHeight, boolean resetOriginalRowHeight)
Shifts rows between startRow and endRow n number of rows. If you use
a negative number, it will shift rows up. Code ensures that rows don't
wrap around 
 
Additionally shifts merged regions that are completely defined in
these rows (ie. merged 2 cells on a row to be shifted). 
 
TODO Might want to add bounds checking here 
 
Parameters:
  startRow - the row to start shifting
  endRow - the row to end shifting
  n - the number of rows to shift
  copyRowHeight - whether to copy the row height during the shift
  resetOriginalRowHeight - whether to set the original row's height
    to the default

前面3个参数和之前一样。如要使行高也一起移动的话,设置「copyRowHeight」参数为「true」。
还有,移动后,原来的行是保留原行高不变还是恢复到默认行高呢?可以设置「resetOriginalRowHeight」参数。为「true」时,则可以恢复到默认行高。反之则保留原行高不变。

示例程序

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    sheet.shiftRows(1, 2, 2, true, true);//第二行和第三行保留原来高度向下移动两行,原栏位恢复默认高度
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample2.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}

再打开新生成的Sample2.xls文件来看看。

 

从上图可以看出,移动后,原行高也被移动了,而原行则恢复到默认行高。

===================

==========================================异常华丽的分割线=============================================================

关于单元格

HSSFCell类定义

这一章开始介绍单元格,其实前面一章已经提到过了,用POI创建单元格,使用「HSSFCell」类,类定义如下。

  • java.lang.Object
  • org.apache.poi.hssf.usermodel.HSSFCell
  • public class HSSFCell extends java.lang.Object

该类包含三个构造方法。

构造方法

protected HSSFCell(Workbook book, Sheet sheet, int row, CellValueRecordInterface cval)
Creates an HSSFCell from a CellValueRecordInterface.

protected HSSFCell(Workbook book, Sheet sheet, int row, short col)
Creates new Cell – Should only be called by HSSFRow.

protected HSSFCell(Workbook book, Sheet sheet, int row, short col, int type)
Deprecated. As of 22-Jan-2002 use @see org.apache.poi.hssf.usermodel.HSSFRow
#createCell(short) and use setCellValue to specify the type lazily.

同之前一样,虽然有三个构造方法,但都是protected类型的,所以直接用构造方法创建单元格行不通,只能通过行来创建单元格。

创建单元格

在一个工作表里创建一个单元格,必须用「HSSFRow」类的「createCell」方法,详细请参照『行里创建单元格』。

使用方法如下:

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFSheet sheet = workbook.createSheet();

HSSFRow row = sheet.createRow(0);

HSSFCell cell = row.createCell((short)2);

读取现有单元格

要读取某一行现有的单元格,使用「HSSFRow」类的「getCell」方法,详细请参照『读取单元格』。

使用方法如下:

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFSheet sheet = workbook.createSheet();

HSSFRow row = sheet.getRow(0);

HSSFCell cell = row.getCell((short)2);

==========

行里创建单元格

下面来看看如何在取得现有行或者在新创建的行里,再创建一个单元格。用POI来创建的话,使用「HSSFRow」类的「createCell」方法。

createCell
public HSSFCell createCell(short column)
Use this to create new cells within the row and return it. 
 
The cell that is returned is a CELL_TYPE_BLANK. The type can be
changed either through calling setCellValue or setCellType. 
 
Parameters:
  column - - the column number this cell represents
Returns:
  HSSFCell a high level representation of the created cell.

(short column)创建指定列号的单元格。列号和行号一样,也是从0开始数的。创建的单元格以「HSSFCell」类的对象返回,关于「HSSFCell」类的介绍,我们放在下面几章进行。

示例程序

自己动手做做看吧。

import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    HSSFWorkbook workbook = new HSSFWorkbook();
 
    HSSFSheet sheet = workbook.createSheet();
    HSSFRow row = sheet.createRow(1);//创建序号为1的行,第2行
 
    HSSFCell cell = row.createCell((short)2);//创建序号为2的单元格,第二行第3格
    cell.setCellValue("test");//写入test
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}

上面的例子里,先创建一个工作表Sheet,然后在工作表里只创建第二行,最后再在这一行创建一个新的单元格,并设上一个值。实行这个程序会生成「sample.xls」这样的Excel文件,打开来看看吧。

 

从图中可以看到,第一行(行号为1,实际是第3行)的第二列(列号是2,实际是第3列)的单元格里,被赋上了值。

==============

读取单元格

如果要从现有的行里取得某一个单元格,POI提供了「HSSFRow」类的「getCell」方法。

getCell
public HSSFCell getCell(short cellnum)
get the hssfcell representing a given column (logical cell)
0-based.
If you ask for a cell that is not defined....you get a null. 
 
Parameters:
  cellnum - 0 based column number
Returns:
  HSSFCell representing that column or null if undefined.

(short cellnum)取得指定列号的单元格。如果是不存在的单元格,会返回「null」。

示例程序

再来动手做做吧。

import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    HSSFWorkbook workbook = new HSSFWorkbook();
 
    HSSFSheet sheet = workbook.createSheet();
    HSSFRow row = sheet.createRow(1);//创建第二行
 
    HSSFCell cell = row.createCell((short)2);//创建第二行第三格
    cell.setCellValue("test");//第二行第三格写入test
 
    for (int i = 0 ; i < 3 ; i++){
      HSSFCell c = row.getCell((short)i);
      if (c  == null){
        System.out.println("第" + i + "列单元格不存在");
      }else{
        System.out.println("第" + i + "列单元格获取成功");
      }
    }
  }
}

上面的例子里,先做成一行(行号为1),然后在这一行的第2列(行号为2)创建单元格,最后再从第0列到第2列依次取得单元格,结果如下:

第0列单元格不存在
第1列单元格不存在
第2列单元格获取成功
===============

读取有值的Excel表格

像下面那样准备一个Excel表格来做做看。

 

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);//取得第一张sheet
    HSSFRow row = sheet.getRow(1);//第2行
 
    for (int i = 0 ; i < 3 ; i++){
      HSSFCell c = row.getCell((short)i);
      if (c  == null){
        System.out.println("第" + i + "列单元格不存在");
      }else{
        System.out.println("第" + i + "列单元格取得成功");
        System.out.println("单元格的值:" + c.getStringCellValue());//getStringCellValue()取得单元格的值
      }
    }
  }
}

结果如下:

第0列单元格取得成功
单元格的值:cell a-2
第1列单元格不存在
第2列单元格取得成功
单元格的值:cell c-2

===========

POI向单元格写入值

前面介绍了如何用POI获取单元格的值,这一节介绍如何用POI向单元格里设定值。和之前获取值一样,对于不同类型的值,写入的方法也是不同的。

方法

boolean

setCellValue(boolean value)

date

setCellValue(java.util.Calendar value)

date

setCellValue(java.util.Date value)

numeric

setCellValue(double value)

string

setCellValue(java.lang.String value)

方法名称相同,但参数类型不同,这样的方法有5个。关于日期型的方法,有Calender型和Date型两种。

当然,POI也可以写入Error值和计算式。

方法

error value

setCellErrorValue(byte value)

Formula

setCellFormula(java.lang.String formula)

先统一看一下各种方法的Doc文档说明吧。

setCellValue(boolean value)

写入boolean型使用「setCellValue(boolean value)」方法。

setCellValue

public void setCellValue(boolean value)

set a boolean value for the cell

 

Parameters:

  value - the boolean value to set this cell to. For formulas

    we'll set the precalculated value, for booleans we'll set

    its value. For other types we will change the cell to a

    boolean cell and set its value.

如果对象单元格不是boolean型的话,则自动转换为boolean型写入。

setCellValue(java.util.Calendar value)

写入Calendar型使用「setCellValue(java.util.Calendar value)」方法。

setCellValue

public void setCellValue(java.util.Calendar value)

set a date value for the cell. Excel treats dates as numeric

so you will need to format the cell as a date.

 

Parameters:

  value - the date value to set this cell to. For formulas

    we'll set the precalculated value, for numerics we'll

    set its value. For othertypes we will change the cell

    to a numeric cell and set its value.

Calendar型的值是作为数值型写入的,如何想表示为日期型的话,需要做格式转换处理。如果对象单元格不是数值型的话,则自动转换为数值型写入。

setCellValue(java.util.Date value)

写入Date型使用「setCellValue(java.util.Date value)」方法。

setCellValue

public void setCellValue(java.util.Date value)

set a date value for the cell. Excel treats dates as numeric

so you will need to format the cell as a date.

 

Parameters:

  value - the date value to set this cell to. For formulas

    we'll set the precalculated value, for numerics we'll

    set its value. For other types we will change the cell

    to a numeric cell and set its value.

Date型的值是作为数值型写入的,如何想表示为日期型的话,需要做格式转换处理。如果对象单元格不是数值型的话,则自动转换为数值型写入。

setCellValue(double value)

写入数值型使用「setCellValue(double value)」方法。

setCellValue

public void setCellValue(double value)

set a numeric value for the cell

 

Parameters:

  value - the numeric value to set this cell to. For formulas

    we'll set the precalculated value, for numerics we'll

    set its value. For other types we will change the cell

    to a numeric cell and set its value.

如果对象单元格不是数值型的话,则自动转换为数值型写入。

setCellValue(java.lang.String value)

写入字符串型使用「setCellValue(java.lang.String value)」方法。

setCellValue

public void setCellValue(java.lang.String value)

set a string value for the cell. Please note that if you are

using full 16 bit unicode you should call setEncoding() first.

 

Parameters:

  value - value to set the cell to. For formulas we'll set

    the formula string, for String cells we'll set its value.

    For other types we will change the cell to a string cell

    and set its value. If value is null then we will change

    the cell to a Blank cell.

要写入中文等文字的话,必须要先使用「setEncoding」方法进行转换。如果对象单元格不是字符串型的话,则自动转换为字符串型写入。还有,如果写入的值是”null”的话,则单元格为空白。

setCellErrorValue(byte value)

写入Error型使用「setCellErrorValue(byte value)」方法。

setCellErrorValue

public void setCellErrorValue(byte value)

set a error value for the cell

 

Parameters:

  value - the error value to set this cell to. For formulas

    we'll set the precalculated value ??? IS THIS RIGHT??? ,

    for errors we'll set its value. For other types we will

    change the cell to an error cell and set its value.

如果对象单元格不是Error型的话,则自动转换为Error型写入。

setCellFormula

写入计算式使用「setCellFormula」方法。

setCellFormula

public void setCellFormula(java.lang.String formula)

--

写入计算式方法的参数虽然是字符串,但Doc文档里一点说明也没有。

示例程序

下面仍然自己动手做一下吧。需要注意的是,对于日期型是作为数值写入的,而数值到底表示什么样的日期是看不出来的,这时只能通过另外指定日期格式。

import java.io.*;

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

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

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

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

import java.util.Calendar;

import java.util.Date;

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

 

    HSSFSheet sheet = workbook.createSheet();

    HSSFRow row = sheet.createRow(1);//创建第二行

 

    HSSFCell cell1 = row.createCell((short)0);//2,1格

    cell1.setCellValue(true);//写入true

 

    HSSFCell cell2 = row.createCell((short)1);//2,2格

    Calendar cal = Calendar.getInstance();//Calendar???

    cell2.setCellValue(cal);//写入Calendar型对象cal

 

    HSSFCell cell3 = row.createCell((short)2);//2,3格

    Date date = new Date(); //日期型

    cell3.setCellValue(date);//写入日期型

 

    HSSFCell cell4 = row.createCell((short)3);//2,4格

    cell4.setCellValue(150);//写入150

 

    HSSFCell cell5 = row.createCell((short)4);//2.5格

    cell5.setCellValue("hello");//写入hello

 

    HSSFRow row2 = sheet.createRow(2);//第三行

 

    HSSFCell cell6 = row2.createCell((short)0);//3,1格

    cell6.setCellErrorValue(HSSFErrorConstants.ERROR_NUM);//写入error型

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

运行结果如下:

 

关于计算式和中文文字的写入,下面几节里将会有具体介绍,还有包括日期型的格式指定。

===============

POI中写入中文

如果你现在下载最新版的POI开发包,你会发现,用POI向单元格里写入字符串时,如果是中文文字或者日文文字的话,已经不需要指定Unicode了,直接就可以显示汉字。之前版本存在的「HSSFCell」类的「setEncoding」方法已经被删除了。下面是被删除的方法说明。

setEncoding
public void setEncoding(short encoding)
set the encoding to either 8 or 16 bit. (US/UK use 8-bit,
rest of the western world use 16bit) 
 
Parameters:
  encoding - either ENCODING_COMPRESSED_UNICODE (0)
    or ENCODING_UTF_16 (1)

示例程序

用下面程序来做做看。

import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    HSSFWorkbook workbook = new HSSFWorkbook();
 
    HSSFSheet sheet = workbook.createSheet();
 
    HSSFRow row1 = sheet.createRow(1);
 
    HSSFCell cell1 = row1.createCell((short)0);
    //cell1.setEncoding(HSSFCell.ENCODING_UTF_16);
    cell1.setCellValue("使用中文");
 
    HSSFCell cell2 = row1.createCell((short)1);
    //cell2.setEncoding(HSSFCell.ENCODING_COMPRESSED_UNICODE);
    cell2.setCellValue("日本語を使う");
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}

运行结果如下:

 

=============

POI获取单元格类值类型

在获取单元格值的时候,不同类型,使用的方法也不一样,所以获取之前,必须要知道类型。这一节就来介绍如何知道单元格里的值是何类型。

要获取单元格值的类型,使用「HSSFCell」类的「getCellType」方法。

getCellType

public int getCellType()

get the cells type (numeric, formula or string)

下面就是类型和定义值的一览表。

Cell type

定义值

值(int)

Blank

CELL_TYPE_BLANK

3

Boolean

CELL_TYPE_BOOLEAN

4

Error

CELL_TYPE_ERROR

5

Formula

CELL_TYPE_FORMULA

2

Numeric

CELL_TYPE_NUMERIC

0

String

CELL_TYPE_STRING

1

示例程序

下面来实际动手做做看。按下图准备一个Excel文件。

 

import java.io.*;

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    HSSFSheet sheet = workbook.getSheetAt(0);

    HSSFRow row = sheet.getRow(1);

 

    HSSFCell cell = row.getCell((short)0);

    System.out.println("A:2=" + getType(cell.getCellType()));

 

    cell = row.getCell((short)1);

    System.out.println("B:2=" + getType(cell.getCellType()));

 

    cell = row.getCell((short)2);

    System.out.println("C:2=" + getType(cell.getCellType()));

 

    cell = row.getCell((short)3);

    System.out.println("D:2=" + getType(cell.getCellType()));

 

    cell = row.getCell((short)4);

    System.out.println("E:2=" + getType(cell.getCellType()));

  }

 

  public static String getType(int type){

    if (type == HSSFCell.CELL_TYPE_BLANK){

      return "CELL_TYPE_BLANK";

    }else if (type == HSSFCell.CELL_TYPE_BOOLEAN){

      return "CELL_TYPE_BOOLEAN";

    }else if (type == HSSFCell.CELL_TYPE_ERROR){

      return "CELL_TYPE_ERROR";

    }else if (type == HSSFCell.CELL_TYPE_FORMULA){

      return "CELL_TYPE_FORMULA";

    }else if (type == HSSFCell.CELL_TYPE_NUMERIC){

      return "CELL_TYPE_NUMERIC";

    }else if (type == HSSFCell.CELL_TYPE_STRING){

      return "CELL_TYPE_STRING";

    }else{

      return "Not defined";

    }

  }

}

实行结果如下:

A:2=CELL_TYPE_NUMERIC

B:2=CELL_TYPE_STRING

C:2=CELL_TYPE_BOOLEAN

D:2=CELL_TYPE_NUMERIC

E:2=CELL_TYPE_ERROR

有一点要注意的是,数值型和日期型都是「CELL_TYPE_NUMERIC」。

日期型检查

到底是数值型还是日期型,可以通过「org.apache.poi.hssf.usermodel.HSSFDateUtil」类的「isCellDateFormatted」方法来检证。

isCellDateFormatted

public static boolean isCellDateFormatted(HSSFCell cell)

Check if a cell contains a date Since dates are

stored internally in Excel as double values we

infer it is a date if it is formatted as such.

因为这个方法是静态的,可以直接调用如下所示。

if (HSSFDateUtil.isCellDateFormatted(cell)){

    /* 日期型 */

}

现在就把之前的示例程序稍微改动一下,再运行看看。

import java.io.*;

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

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    HSSFSheet sheet = workbook.getSheetAt(0);

    HSSFRow row = sheet.getRow(1);

 

    HSSFCell cell = row.getCell((short)0);

    System.out.println("A:2=" + getType(cell));

 

    cell = row.getCell((short)1);

    System.out.println("B:2=" + getType(cell));

 

    cell = row.getCell((short)2);

    System.out.println("C:2=" + getType(cell));

 

    cell = row.getCell((short)3);

    System.out.println("D:2=" + getType(cell));

 

    cell = row.getCell((short)4);

    System.out.println("E:2=" + getType(cell));

  }

 

  public static String getType(HSSFCell cell){

    int type = cell.getCellType();

 

    if (type == HSSFCell.CELL_TYPE_BLANK){

      return "CELL_TYPE_BLANK";

    }else if (type == HSSFCell.CELL_TYPE_BOOLEAN){

      return "CELL_TYPE_BOOLEAN";

    }else if (type == HSSFCell.CELL_TYPE_ERROR){

      return "CELL_TYPE_ERROR";

    }else if (type == HSSFCell.CELL_TYPE_FORMULA){

      return "CELL_TYPE_FORMULA";

}else if (type == HSSFCell.CELL_TYPE_NUMERIC){

//检查日期类型

      if (HSSFDateUtil.isCellDateFormatted(cell)){

        return "CELL_TYPE_DATE";

      }else{

        return "CELL_TYPE_NUMERIC";

      }

    }else if (type == HSSFCell.CELL_TYPE_STRING){

      return "CELL_TYPE_STRING";

    }else{

      return "Not defined";

    }

  }

}

实行结果如下:

A:2=CELL_TYPE_NUMERIC

B:2=CELL_TYPE_STRING

C:2=CELL_TYPE_BOOLEAN

D:2=CELL_TYPE_DATE

E:2=CELL_TYPE_ERROR

这一次,日期型也可以被检查出来了。

=========

POI获取单元格类的值

这一节介绍如何获取单元格的值。在POI里,对于不同类型的单元格的值,所调用的方法是不一样的。

函数名

boolean型

getBooleanCellValue()

java.util.Date型

getDateCellValue()

byte型

getErrorCellValue()

double型

getNumericCellValue()

java.lang.String型

getStringCellValue()

java.lang.String型

getCellFormula()

如果单元格里是String型的值,调用方法「getStringCellValue」,数值型的话,则调用「getNumericCellValue」。再一起来看看其它方法。

getBooleanCellValue

获取boolean型的値,调用「getBooleanCellValue」方法。

getBooleanCellValue

public boolean getBooleanCellValue()

get the value of the cell as a boolean. For strings, numbers,

and errors, we throw an exception. For blank cells we return

a false.

如果调用这个方法来获取字符串,数值型的值的话,会发生Exception异常,如果对象单元格里不含值,则返回「false」。

getDateCellValue

获取日期Date型时,调用「getDateCellValue」方法。

getDateCellValue

public java.util.Date getDateCellValue()

get the value of the cell as a date. For strings we

throw an exception.

For blank cells we return a null.

如果用这个方法来获取字符串时,会有Exception异常发生,如果对象单元格里不含值,则返回「null」。

getErrorCellValue

单元格如果是Error值,比如#VALUE!等,这时可以使用「getErrorCellValue」方法。

getErrorCellValue

public byte getErrorCellValue()

get the value of the cell as an error code. For strings,

numbers, and booleans, we throw an exception. For blank

cells we return a 0.

字符串,数值型,布尔型的值用这个方法的话,会产生异常,而单元格里值为空时则返回「0」。

对于单元格的Error值类型,在POI里的「org.apache.poi.hssf.usermodel.HSSFErrorConstants」有定义列表如下:

常量名

错误代码

Excel里的Error值

public static final byte ERROR_DIV_0

7

#DIV/0!

public static final byte ERROR_NA

42

#N/A

public static final byte ERROR_NAME

29

#NAME?

public static final byte ERROR_NULL

0

#NULL!

public static final byte ERROR_NUM

36

#NUM!

public static final byte ERROR_REF

23

#REF!

public static final byte ERROR_VALUE

15

#VALUE!

所以这里要注意了,Excel的ERROR.TYPE函数所返回的值,和POI所定义的是不一样的。

getNumericCellValue

读取数值型时,调用「getNumericCellValue」方法。

getNumericCellValue

public double getNumericCellValue()

get the value of the cell as a number. For strings

we throw an exception.

For blank cells we return a 0.

用这个方法来读取字符串类型时,会有Exception发生,如果单元格里值为空时则返回「0」。

getStringCellValue

字符串类型取得时,使用「getStringCellValue」方法。

getStringCellValue

public java.lang.String getStringCellValue()

get the value of the cell as a string - for numeric cells

we throw an exception.

For blank cells we return an empty string. For formulaCells

that are not string Formulas, we return empty String

同样的,用这个方法来读取数值型时,也会有异常Exception发生。单元格值为空时,则返回空白。

getCellFormula

读取单元格里的计算式时,使用「getCellFormula」方法。

getCellFormula

public java.lang.String getCellFormula()

--

单元格里如果是计算式的话,则把计算式作为字符串来获取。关于具体内容,在最新文档里,竟然没有,不知道为什么。

示例程序

下面我们就在一个Excel文件里,设定各种值,然后用上面的方法来读取。像下图一样准备一个Excel文件吧。

 

通过下面程序来获取各种类型的单元格的值。

import java.io.*;

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    FileInputStream in = null;

    HSSFWorkbook workbook = null;

 

    try{

      in = new FileInputStream("sample.xls");

      POIFSFileSystem fs = new POIFSFileSystem(in);

      workbook = new HSSFWorkbook(fs);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try{

        in.close();

      }catch (IOException e){

        System.out.println(e.toString());

      }

    }

 

    HSSFSheet sheet = workbook.getSheetAt(0);

    HSSFRow row = sheet.getRow(1);

 

    HSSFCell cell = row.getCell((short)0);

    System.out.println(cell.getNumericCellValue());

 

    cell = row.getCell((short)1);

    System.out.println(cell.getStringCellValue());

 

    cell = row.getCell((short)2);

    System.out.println(cell.getBooleanCellValue());

 

    cell = row.getCell((short)3);

    System.out.println(cell.getErrorCellValue());

 

    cell = row.getCell((short)4);

    System.out.println(cell.getDateCellValue());

  }

}

运行结果如下:

125.0

你好

true

7

Tue Oct 27 00:00:00 JST 2009

和预想的一样吧

POI读取写入函数式

单元格里可以写入函数,自动进行计算操作,这也是Excel功能强大的一方面。前面也提到过,使用POI,往单元格里写入函数,使用「setCellFormula」方法,要获取单元格的函数则使用「getCellFormula」方法。

两个方法,在DOC文档里都没有详细说明,原因不明。总之,先动手做做看。首先来看看如何从单元格取出函数式。

 

上图中,在单元格「C:2」里的函数式是「=A2*B2」,「C:3」里的函数式是「=SUM(A3:B3)」。

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    HSSFRow row1 = sheet.getRow(1);
 
    HSSFCell cell1 = row1.getCell((short)2);
    System.out.println("C:2的函数式 " + cell1.getCellFormula());//getCellFormula()取得函数式
 
    HSSFRow row2 = sheet.getRow(2);
 
    HSSFCell cell2 = row2.getCell((short)2);
    System.out.println("C:3的函数式 " + cell2.getCellFormula());
  }
}

实行结果如下:

C:2的函数式 A2*B2
C:3的函数式 SUM(A3:B3)

如上所示,函数式被正常取出,只是函数式前的「=」被省略了。

下面再来看看如何向单元格写入函数式。还是利用之前的Excel文件,「C:2」单元格里写入「A2+B2」,「C:3」单元格里写入「AVERAGE(A3,B3)」这样的函数式。

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    HSSFRow row1 = sheet.getRow(1);
    HSSFCell cell1 = row1.createCell((short)2);
    cell1.setCellFormula("A2+B2");// setCellFormula写入函数式
 
    HSSFRow row2 = sheet.getRow(2);
    HSSFCell cell2 = row2.createCell((short)2);
    cell2.setCellFormula("AVERAGE(A3,B3)");
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample3.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}

实行结果如下:

 

到底什么样的函数式可以用,什么样的不能用,这一点还不是很明白,但至少一部分是可以用的。

最后要注意的就是,对于使用getCell方法获取的单元格,函数式是不能被写入的。因此对于已经存在的单元格,在写入函数式时,只能先通过createCell方法创建单元格,再写入函数式。

POI获取行单元格相关信息

有时可能你想要知道行里面单元格的具体信息,比方说,该行实际上有多少单元格,最初的单元格在什么位置,最后的单元格又在哪里?用POI也可以实现。
要取得某一行实际存在的单元格的总数,使用「HSSFRow」类的「getPhysicalNumberOfCells」方法。

getPhysicalNumberOfCells
public int getPhysicalNumberOfCells()
gets the number of defined cells (NOT number of cells in the
actual row!). That is to say if only columns 0,4,5 have values
then there would be 3. 
 
Returns:
  int representing the number of defined cells in the row.

要想知道最初的单元格的位置,可以使用「HSSFRow」类的「getFirstCellNum」方法。

getFirstCellNum
public short getFirstCellNum()
get the number of the first cell contained in this row. 
 
Returns:
  short representing the first logical cell in the row,
or -1 if the row does not contain any cells.

你也可以使用「HSSFRow」类的「getLastCellNum」方法来获取最后的单元格的位置,但这里要注意一点,如果单元格存在,如下面的API文档所说,获取的值是实际列号再加上1,在以前的版本可不是这样的。

getLastCellNum
public short getLastCellNum()
get the number of the last cell contained in this row. 
 
Returns:
  short representing the last logical cell in the row PLUS ONE,
 or -1 if the row does not contain any cells.

需要注意的是,POI在获取最初单元格位置和最后单元格位置时,返回的值并不是某一行特有的,而是针对所有的行。也就是说,上面的两个方法,针对所有的行,返回一个最小的列号和最大的列号。因此,不管对于哪一行,实行上面的两个方法,返回的值都是一样的。

示例程序

自己动手做做看吧。

import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    HSSFWorkbook workbook = new HSSFWorkbook();
 
    HSSFSheet sheet = workbook.createSheet();
    HSSFRow row = sheet.createRow(1);
 
    System.out.println("创建单元格前的状态:");
    System.out.println("First:" + row.getFirstCellNum());
    System.out.println("Last:" + row.getLastCellNum());
    System.out.println("Total:"
                + row.getPhysicalNumberOfCells() + "\n");
 
    row.createCell((short)1);
 
    System.out.println("创建第二列(列号为1)单元格:");
    System.out.println("First:" + row.getFirstCellNum());
    System.out.println("Last:" + row.getLastCellNum());
    System.out.println("Total:"
                + row.getPhysicalNumberOfCells() + "\n");
 
    row.createCell((short)3);
 
    System.out.println("创建第四列(列号为3)单元格:");
    System.out.println("First:" + row.getFirstCellNum());
    System.out.println("Last:" + row.getLastCellNum());
    System.out.println("Total:"
                + row.getPhysicalNumberOfCells() + "\n");
  }
}

结果如下:

创建单元格前的状态:
First:-1
Last:-1
Total:0
 
创建第二列(列号为1)单元格:
First:1
Last:2
Total:1
 
创建第四列(列号为3)单元格:
First:1
Last:4
Total:2

一行当中没有单元格的情况下,调用「getFirstCellNum」方法和「getLastCellNum」方法,返回值都是「-1」。有单元格时,调用「getLastCellNum」方法,返回的值总是实际列号再加上1(实际第几列)。

===============

从现有的Excel文件读取单元格信息

再来看看如何从现有的Excel文件里读取单元格信息。

 

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
    HSSFRow row = sheet.getRow(1);
 
    System.out.println("First:" + row.getFirstCellNum());
    System.out.println("Last:" + row.getLastCellNum());
    System.out.println("Total:"
                 + row.getPhysicalNumberOfCells() + "\n");
 
    row = sheet.getRow(2);
 
    System.out.println("First:" + row.getFirstCellNum());
    System.out.println("Last:" + row.getLastCellNum());
    System.out.println("Total:"
                 + row.getPhysicalNumberOfCells() + "\n");
  }
}

结果如下:

First:0
Last:4
Total:2
 
First:0
Last:4
Total:2

接下来对这个Excel文件在另外的单元格里输入值,再用同样的程序(稍有变化)来运行看看。

 

import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
    HSSFRow row = sheet.getRow(1);
 
    System.out.println("First:" + row.getFirstCellNum());
    System.out.println("Last:" + row.getLastCellNum());
    System.out.println("Total:"
                   + row.getPhysicalNumberOfCells() + "\n");
 
    row = sheet.getRow(2);
 
    System.out.println("First:" + row.getFirstCellNum());
    System.out.println("Last:" + row.getLastCellNum());
    System.out.println("Total:"
                   + row.getPhysicalNumberOfCells() + "\n");
 
    row = sheet.getRow(3);
 
    System.out.println("First:" + row.getFirstCellNum());
    System.out.println("Last:" + row.getLastCellNum());
    System.out.println("Total:"
                   + row.getPhysicalNumberOfCells() + "\n");
  }
}

结果如下:

First:0
Last:5
Total:2
 
First:0
Last:5
Total:2
 
First:0
Last:5
Total:1

虽然对于不同的行,单元格的总数不一样,但不管哪一行,它的最小列号和最大列号都是一样的。

 

==========================================异常华丽的分割线=============================================================

POI样式的设定

HSSFCellStyle类定义

这一节开始介绍如何通过POI来进行单元格格式的设定。设定格式使用「HSSFCellStyle」类,关于它的类定义如下:

  • java.lang.Object
  • org.apache.poi.hssf.usermodel.HSSFCellStyle
  • public class HSSFCellStyle extends java.lang.Object

它有一个构造方法。

构造方法

protected HSSFCellStyle(short index, ExtendedFormatRecord rec)
Creates new HSSFCellStyle why would you want to do this??

虽然有构造方法,但却是protected的,所以不能直接使用,要通过一个工作簿workbook来生成格式对象。

在POI里,格式好像是以workbook为单位来管理的,所以要先作成一个格式对象,保存在workbook里,然后再对已生成好的单元格进行设定。

在单元格里指定格式

要作成一个格式对象,可以使用「HSSFWorkbook」类的「createCellStyle」方法。

createCellStyle

public HSSFCellStyle createCellStyle()

create a new Cell style and add it to the workbook's style table

 

Returns:

  the new Cell Style object

另外,要取出现有的格式对象的话,使用「HSSFWorkbook」类的「getCellStyleAt」方法,这个方法有参数,是被保存格式的INDEX号。

getCellStyleAt

public HSSFCellStyle getCellStyleAt(short idx)

get the cell style object at the given index

 

Parameters:

  idx - index within the set of styles

Returns:

  HSSFCellStyle object at the index

还有,对于某一个单元格,也可以取出它的格式对象。这时要使用「HSSFCell」类的「getCellStyle」方法。

getCellStyle

public HSSFCellStyle getCellStyle()

get the style for the cell. This is a reference to a cell style

contained in the workbook object.

这样的话,不管是新创建的或者是从现有的单元格里取出来的格式对象,都可以用来对某一个单元格进行格式的设定。设定方法使用「HSSFCell」类的「setCellStyle」方法。

setCellStyle

public void setCellStyle(HSSFCellStyle style)

set the style for the cell. The style should be an HSSFCellStyle

created/retreived from the HSSFWorkbook.

 

Parameters:

  style - reference contained in the workbook

示例程序

关于格式的详细设定方法,下几节再讲,先做个示例程序来看看。

import java.io.*;

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

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

 

    HSSFSheet sheet = workbook.createSheet();

    HSSFRow row = sheet.createRow(1);//第二行

 

    HSSFCell cell = row.createCell((short)0);//2,1格

    cell.setCellValue("sample");//写入sample

 

HSSFCellStyle style = workbook.createCellStyle();//创建个workbook的HSSFCellStyle格式对象style

 

//设定格式

    style.setFillBackgroundColor(HSSFColor.WHITE.index);

    style.setFillForegroundColor(HSSFColor.LIGHT_ORANGE.index);

    style.setFillPattern(HSSFCellStyle.THICK_HORZ_BANDS);

 

    cell.setCellStyle(style);//对2,1格写入上面的格式

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

按上面程序,在某一个单元格里设定了顔色。运行结果如下:

 

好了,从下一节开始详细介绍单元格格式的设定。

===============

POI单元格颜色设定

先从单元格顔色设定开始介绍。单元格的顔色有前景色和背景色。

前景色的设定使用「HSSFCellStyle」类的「setFillForegroundColor」方法。

setFillForegroundColor

public void setFillForegroundColor(short bg)

set the foreground fill color

 

Parameters:

  bg - color

背景色的设定则使用「HSSFCellStyle」类的「setFillBackgroundColor」方法。

setFillBackgroundColor

public void setFillBackgroundColor(short bg)

set the background fill color.

 

Parameters:

  bg - color

两个方法都是通过参数来设定具体什么顔色。该参数类型为short型,在「HSSFColor」类里,准备了各种各样顔色的定义值。

HSSFColor

HSSFColor类定义如下:

  • java.lang.Object
  • org.apache.poi.hssf.util.HSSFColor
  • public class HSSFColor extends java.lang.Object

而各种顔色又是作为HSSFColor类的子类,定义一览表如下:

HSSFColor.AQUA

HSSFColor.BLACK

HSSFColor.BLUE

HSSFColor.BLUE_GREY

HSSFColor.BRIGHT_GREEN

HSSFColor.BROWN

HSSFColor.CORAL

HSSFColor.CORNFLOWER_BLUE

HSSFColor.DARK_BLUE

HSSFColor.DARK_GREEN

HSSFColor.DARK_RED

HSSFColor.DARK_TEAL

HSSFColor.DARK_YELLOW

HSSFColor.GOLD

HSSFColor.GREEN

HSSFColor.GREY_25_PERCENT

HSSFColor.GREY_40_PERCENT

HSSFColor.GREY_50_PERCENT

HSSFColor.GREY_80_PERCENT

HSSFColor.INDIGO

HSSFColor.LAVENDER

HSSFColor.LEMON_CHIFFON

HSSFColor.LIGHT_BLUE

HSSFColor.LIGHT_CORNFLOWER_BLUE

HSSFColor.LIGHT_GREEN

HSSFColor.LIGHT_ORANGE

HSSFColor.LIGHT_TURQUOISE

HSSFColor.LIGHT_YELLOW

HSSFColor.LIME

HSSFColor.MAROON

HSSFColor.OLIVE_GREEN

HSSFColor.ORANGE

HSSFColor.ORCHID

HSSFColor.PALE_BLUE

HSSFColor.PINK

HSSFColor.PLUM

HSSFColor.RED

HSSFColor.ROSE

HSSFColor.ROYAL_BLUE

HSSFColor.SEA_GREEN

HSSFColor.SKY_BLUE

HSSFColor.TAN

HSSFColor.TEAL

HSSFColor.TURQUOISE

HSSFColor.VIOLET

HSSFColor.WHITE

HSSFColor.YELLOW

 

设定顔色时,用这些子类的静态常量「index」作为参数,使用方法如下:

HSSFWorkbook workbook = new HSSFWorkbook();

 

HSSFCellStyle style = workbook.createCellStyle();

style.setFillForegroundColor(HSSFColor.LIME.index);

style.setFillBackgroundColor(HSSFColor.GREEN.index);

如果这些顔色还不够你用的话,那么下一节再介绍怎么设定自己想要的顔色。

填充模式

指定填充模式的话,使用「HSSFCellStyle」类的「setFillPattern」方法。

setFillPattern

public void setFillPattern(short fp)

setting to one fills the cell with the foreground color

... No idea about other values

 

Parameters:

  fp - fill pattern (set to 1 to fill w/foreground color)

指定的填充模式,在「HSSFCellStyle」类里也有定义,类型为static short型,如下所示:

说明

NO_FILL

No background

SOLID_FOREGROUND

Solidly filled

FINE_DOTS

Small fine dots

ALT_BARS

Wide dots

SPARSE_DOTS

Sparse dots

THICK_HORZ_BANDS

Thick horizontal bands

THICK_VERT_BANDS

Thick vertical bands

THICK_BACKWARD_DIAG

Thick backward facing diagonals

THICK_FORWARD_DIAG

Thick forward facing diagonals

BIG_SPOTS

Large spots

BRICKS

Brick-like layout

THIN_HORZ_BANDS

Thin horizontal bands

THIN_VERT_BANDS

Thin vertical bands

THIN_BACKWARD_DIAG

Thin backward diagonal

THIN_FORWARD_DIAG

Thin forward diagonal

SQUARES

Squares

DIAMONDS

Diamonds

实际的使用方法如下:

HSSFWorkbook workbook = new HSSFWorkbook();

 

HSSFCellStyle style = workbook.createCellStyle();

style.setFillForegroundColor(HSSFColor.LIME.index);

style.setFillBackgroundColor(HSSFColor.GREEN.index);

 

style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

示例程序

这就实际动手做做看吧,首先看一下定义的顔色到底是什么顔色,全部拉上来看看。

import java.io.*;

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

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

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

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

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

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

 

public class POISample{

  static HSSFWorkbook workbook;

 

  public static void main(String[] args){

    workbook = new HSSFWorkbook();

 

    HSSFSheet sheet = workbook.createSheet();

 

    HSSFRow row[] = new HSSFRow[12];

    for (int i = 0; i < 12 ; i++){

      row[i] = sheet.createRow(i);

    }

 

    HSSFCell cell[][] = new HSSFCell[12][4];

    for (int i = 0; i < 12; i++){

      for (int j = 0; j < 4 ; j++){

        cell[i][j] = row[i].createCell((short)j);

      }

    }

 

    setStyle(cell[0][0], "AQUA", HSSFColor.AQUA.index);

    setStyle(cell[0][1], "BLACK", HSSFColor.BLACK.index);

    setStyle(cell[0][2], "BLUE", HSSFColor.BLUE.index);

    setStyle(cell[0][3], "BLUE_GREY", HSSFColor.BLUE_GREY.index);

    setStyle(cell[1][0], "BRIGHT_GREEN",

                              HSSFColor.BRIGHT_GREEN.index);

    setStyle(cell[1][1], "BROWN", HSSFColor.BROWN.index);

    setStyle(cell[1][2], "CORAL", HSSFColor.CORAL.index);

    setStyle(cell[1][3], "CORNFLOWER_BLUE",

                              HSSFColor.CORNFLOWER_BLUE.index);

    setStyle(cell[2][0], "DARK_BLUE", HSSFColor.DARK_BLUE.index);

    setStyle(cell[2][1], "DARK_GREEN", HSSFColor.DARK_GREEN.index);

    setStyle(cell[2][2], "DARK_RED", HSSFColor.DARK_RED.index);

    setStyle(cell[2][3], "DARK_TEAL", HSSFColor.DARK_TEAL.index);

    setStyle(cell[3][0], "DARK_YELLOW",

                              HSSFColor.DARK_YELLOW.index);

    setStyle(cell[3][1], "GOLD", HSSFColor.GOLD.index);

    setStyle(cell[3][2], "GREEN", HSSFColor.GREEN.index);

    setStyle(cell[3][3], "GREY_25_PERCENT",

                              HSSFColor.GREY_25_PERCENT.index);

    setStyle(cell[4][0], "GREY_40_PERCENT",

                              HSSFColor.GREY_40_PERCENT.index);

    setStyle(cell[4][1], "GREY_50_PERCENT",

                              HSSFColor.GREY_50_PERCENT.index);

    setStyle(cell[4][2], "GREY_80_PERCENT",

                              HSSFColor.GREY_80_PERCENT.index);

    setStyle(cell[4][3], "INDIGO", HSSFColor.INDIGO.index);

    setStyle(cell[5][0], "LAVENDER", HSSFColor.LAVENDER.index);

    setStyle(cell[5][1], "LEMON_CHIFFON",

                              HSSFColor.LEMON_CHIFFON.index);

    setStyle(cell[5][2], "LIGHT_BLUE",

                              HSSFColor.LIGHT_BLUE.index);

    setStyle(cell[5][3], "LIGHT_CORNFLOWER_BLUE",

                          HSSFColor.LIGHT_CORNFLOWER_BLUE.index);

    setStyle(cell[6][0], "LIGHT_GREEN",

                              HSSFColor.LIGHT_GREEN.index);

    setStyle(cell[6][1], "LIGHT_ORANGE",

                              HSSFColor.LIGHT_ORANGE.index);

    setStyle(cell[6][2], "LIGHT_TURQUOISE",

                              HSSFColor.LIGHT_TURQUOISE.index);

    setStyle(cell[6][3], "LIGHT_YELLOW",

                              HSSFColor.LIGHT_YELLOW.index);

    setStyle(cell[7][0], "LIME", HSSFColor.LIME.index);

    setStyle(cell[7][1], "MAROON", HSSFColor.MAROON.index);

    setStyle(cell[7][2], "OLIVE_GREEN",

                              HSSFColor.OLIVE_GREEN.index);

    setStyle(cell[7][3], "ORANGE", HSSFColor.ORANGE.index);

    setStyle(cell[8][0], "ORCHID", HSSFColor.ORCHID.index);

    setStyle(cell[8][1], "PALE_BLUE", HSSFColor.PALE_BLUE.index);

    setStyle(cell[8][2], "PINK", HSSFColor.PINK.index);

    setStyle(cell[8][3], "PLUM", HSSFColor.PLUM.index);

    setStyle(cell[9][0], "RED", HSSFColor.RED.index);

    setStyle(cell[9][1], "ROSE", HSSFColor.ROSE.index);

    setStyle(cell[9][2], "ROYAL_BLUE",

                              HSSFColor.ROYAL_BLUE.index);

    setStyle(cell[9][3], "SEA_GREEN", HSSFColor.SEA_GREEN.index);

    setStyle(cell[10][0], "SKY_BLUE", HSSFColor.SKY_BLUE.index);

    setStyle(cell[10][1], "TAN", HSSFColor.TAN.index);

    setStyle(cell[10][2], "TEAL", HSSFColor.TEAL.index);

    setStyle(cell[10][3], "TURQUOISE",

                              HSSFColor.TURQUOISE.index);

    setStyle(cell[11][0], "VIOLET", HSSFColor.VIOLET.index);

    setStyle(cell[11][1], "WHITE", HSSFColor.WHITE.index);

    setStyle(cell[11][2], "YELLOW", HSSFColor.YELLOW.index);

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

 

  public static void setStyle(HSSFCell cell, String col, short fg){

    HSSFCellStyle style = workbook.createCellStyle();

    style.setFillForegroundColor(fg);

    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

    cell.setCellStyle(style);

 

    cell.setCellValue(col);

  }

}

上面程序只指定了「ForegroundColor」,填充模式是「SOLID_FOREGROUND」,因此顔色应该是全部充满整个单元格的。运行结果如下:

 

下面再对填充模式进行各种修改来看看。

import java.io.*;

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

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

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

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

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

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

 

public class POISample{

  static HSSFWorkbook workbook;

 

  public static void main(String[] args){

    workbook = new HSSFWorkbook();

 

    HSSFSheet sheet = workbook.createSheet();

 

    HSSFRow row[] = new HSSFRow[5];

    for (int i = 0; i < 5 ; i++){

      row[i] = sheet.createRow(i);

    }

 

    HSSFCell cell[][] = new HSSFCell[5][4];

    for (int i = 0; i < 5; i++){

      for (int j = 0; j < 4 ; j++){

        cell[i][j] = row[i].createCell((short)j);

      }

    }

 

    setStyle(cell[0][0], "NO_FILL", HSSFCellStyle.NO_FILL);

    setStyle(cell[0][1], "SOLID_FOREGROUND",

                              HSSFCellStyle.SOLID_FOREGROUND);

    setStyle(cell[0][2], "FINE_DOTS", HSSFCellStyle.FINE_DOTS);

    setStyle(cell[0][3], "ALT_BARS", HSSFCellStyle.ALT_BARS);

 

    setStyle(cell[1][0], "SPARSE_DOTS", HSSFCellStyle.SPARSE_DOTS);

    setStyle(cell[1][1], "THICK_HORZ_BANDS",

                              HSSFCellStyle.THICK_HORZ_BANDS);

    setStyle(cell[1][2], "THICK_VERT_BANDS",

                              HSSFCellStyle.THICK_VERT_BANDS);

    setStyle(cell[1][3], "THICK_BACKWARD_DIAG",

                              HSSFCellStyle.THICK_BACKWARD_DIAG);

 

    setStyle(cell[2][0], "THICK_FORWARD_DIAG",

                              HSSFCellStyle.THICK_FORWARD_DIAG);

    setStyle(cell[2][1], "BIG_SPOTS", HSSFCellStyle.BIG_SPOTS);

    setStyle(cell[2][2], "BRICKS", HSSFCellStyle.BRICKS);

    setStyle(cell[2][3], "THIN_HORZ_BANDS",

                              HSSFCellStyle.THIN_HORZ_BANDS);

 

    setStyle(cell[3][0], "THIN_VERT_BANDS",

                              HSSFCellStyle.THIN_VERT_BANDS);

    setStyle(cell[3][1], "THIN_BACKWARD_DIAG",

                              HSSFCellStyle.THIN_BACKWARD_DIAG);

    setStyle(cell[3][2], "THIN_FORWARD_DIAG",

                              HSSFCellStyle.THIN_FORWARD_DIAG);

    setStyle(cell[3][3], "SQUARES", HSSFCellStyle.SQUARES);

 

    setStyle(cell[4][0], "DIAMONDS", HSSFCellStyle.DIAMONDS);

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

 

  public static void setStyle(HSSFCell cell, String fps,

                              short fp){

    HSSFCellStyle style = workbook.createCellStyle();

    style.setFillForegroundColor(HSSFColor.WHITE.index);

    style.setFillForegroundColor(HSSFColor.LIGHT_ORANGE.index);

    style.setFillPattern(fp);

    cell.setCellStyle(style);

 

    cell.setCellValue(fps);

  }

}

上面固定了「ForegroundColor」和「BackgroundColor」,而填充模式则做了各种尝试。运行结果如下:

 

 

================

POI调色板操作

上一节介绍了如何设定POI里已经准备好的顔色,但有时你想要的顔色不在这个范围内,怎么办呢?这一节就来介绍如何使用调色板的RGB的值来设定你喜欢的顔色。

要创建一个新的颜色,在调色板里如果有这个对应值那当然没问题。那有没有可能你想要的顔色在调色板里也没有呢?关于这个解决办法还不知道。总之,先从有对应值的来做做看吧。

首先取出现在正在使用的调色板。调色板是由「HSSFPalette」类定义的。其定义如下:

  • java.lang.Object
  • org.apache.poi.hssf.usermodel.HSSFPalette
  • public class HSSFPalette extends java.lang.Object

构造方法虽然有一个,但仍然是protected的,所以也不能直接使用,而要用「HSSFWorkbook」类的「getCustomPalette」方法来取得调色板对象。

getCustomPalette

public HSSFPalette getCustomPalette()

--

非常遗憾,该方法也是没有任何说明,原因不明。先按下面的方法使用吧。

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFPalette palette = workbook.getCustomPalette();

调色板取得后,就可以使用「HSSFPalette」类的「setColorAtIndex」方法设定自己想要的顔色了。

setColorAtIndex

public void setColorAtIndex(short index,

              byte red, byte green, byte blue)

Sets the color at the given offset

 

Parameters:

  index - the palette index, between 0x8 to

          0x40 inclusive

  red - the RGB red component, between 0

          and 255 inclusive

  green - the RGB green component, between 0

          and 255 inclusive

  blue - the RGB blue component, between 0

          and 255 inclusive

第一个参数设定你想要顔色的主色调的index号,如上一节一样,使用「HSSFColor」类的子类。

HSSFColor.RED.index

剩下的三个参数,通过设定RGB值来调节你想要的顔色。每一个都可以设定0~255的值。

HSSFWorkbook workbook = new HSSFWorkbook();

 

HSSFPalette palette = workbook.getCustomPalette();

palette.setColorAtIndex(HSSFColor.RED.index,

                 (byte)100, (byte)0, (byte)0);

示例程序

自己做做看吧,首先要确定你想要顔色的主色调。

import java.io.*;

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

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

 

    HSSFSheet sheet = workbook.createSheet();

 

    HSSFRow row = sheet.createRow(1);

    HSSFCell cell = row.createCell((short)1);

 

    HSSFCellStyle style = workbook.createCellStyle();

    style.setFillForegroundColor(HSSFColor.RED.index);

    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

    cell.setCellStyle(style);

 

    cell.setCellValue("RED");

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

上面程序对一个单元格设定了红色「HSSFColor.RED」的主色调,运行结果如下:

 

下面就对这个顔色通过RGB值来做一些改动吧。

import java.io.*;

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

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

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

 

    HSSFPalette palette = workbook.getCustomPalette();

    palette.setColorAtIndex(HSSFColor.RED.index,

                    (byte)128, (byte)0, (byte)0);

 

    HSSFSheet sheet = workbook.createSheet();

 

    HSSFRow row = sheet.createRow(1);

    HSSFCell cell = row.createCell((short)1);

 

    HSSFCellStyle style = workbook.createCellStyle();

    style.setFillForegroundColor(HSSFColor.RED.index);

    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

    cell.setCellStyle(style);

 

    cell.setCellValue("RED");

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

上面程序使用调色板对红色「HSSFColor.RED」进行了一些改动,之后用前面一个例子的方法同样设定红色,但得到的结果却是不一样的。运行结果如下:

 

因为调色板在一个workbook里是共有的,所以如果用调色板改变了某一种顔色,下次使用时,相同的顔色就全部改变了。

 

===============

POI设置边框 

在做一个电子表格时,边框的设置有时是必不可少的。这一节就来介绍边框,设置时,可以指定边框的位置,边框的种类,边框的顔色。

首先是边框的位置和种类。对单元格设置边框时,有上下左右位置之分,所以POI也准备了四个不同的方法。

上部的边框:

setBorderTop

public void setBorderTop(short border)

set the type of border to use for the top

border of the cell

 

Parameters:

  border - type

下部的边框:

setBorderBottom

public void setBorderBottom(short border)

set the type of border to use for the

bottom border of the cell

 

Parameters:

  border - type

左侧的边框:

setBorderLeft

public void setBorderLeft(short border)

set the type of border to use for the

left border of the cell

 

Parameters:

  border - type

右侧的边框:

setBorderRight

public void setBorderRight(short border)

set the type of border to use for the

right border of the cell

 

Parameters:

  border - type

参数通过表示边框种类的short型值来指定。下面是定义在「HSSFCellStyle」类里可以被指定值的一览表。

说明

BORDER_DASH_DOT

dash-dot border

BORDER_DASH_DOT_DOT

dash-dot-dot border

BORDER_DASHED

dash border

BORDER_DOTTED

dot borderhair-line border

BORDER_DOUBLE

double-line border

BORDER_HAIR

hair-line border

BORDER_MEDIUM

Medium border

BORDER_MEDIUM_DASH_DOT

medium dash-dot border

BORDER_MEDIUM_DASH_DOT_DOT

medium dash-dot-dot border

BORDER_MEDIUM_DASHED

Medium dashed border

BORDER_NONE

No border

BORDER_SLANTED_DASH_DOT

slanted dash-dot border

BORDER_THICK

Thick border

BORDER_THIN

Thin border

比如要在单元格下边框设置两重线的边框时,按如下方法:

HSSFWorkbook workbook = new HSSFWorkbook();

 

HSSFCellStyle style = workbook.createCellStyle();

style.setBorderRight(HSSFCellStyle.BORDER_THIN);

下面再看看指定边框顔色。同样也分为上下左右边框来操作。

上部的边框:

setTopBorderColor

public void setTopBorderColor(short color)

set the color to use for the top border

 

Parameters:

  color -

下部的边框:

setBottomBorderColor

public void setBottomBorderColor(short color)

set the color to use for the bottom border

 

Parameters:

  color -

左侧的边框:

setLeftBorderColor

public void setLeftBorderColor(short color)

set the color to use for the left border

 

Parameters:

  color -

右侧的边框:

setRightBorderColor

public void setRightBorderColor(short color)

set the color to use for the right border

 

Parameters:

  color -

仍然是通过参数来指定顔色,而且使用方法和前面一节也是一样。具体如下:

HSSFWorkbook workbook = new HSSFWorkbook();

 

HSSFCellStyle style = workbook.createCellStyle();

style.setRightBorderColor(HSSFColor.RED.index);

style.setBorderRight(HSSFCellStyle.BORDER_THIN);

示例程序

实际动手做做吧。首先看看如何设置上下左右的边框。

import java.io.*;

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

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

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

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

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

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

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

 

public class POISample{

  public static void main(String[] args){

    HSSFWorkbook workbook = new HSSFWorkbook();

    HSSFSheet sheet = workbook.createSheet();

 

    HSSFRow row = sheet.createRow(1);

    HSSFCell cell1 = row.createCell((short)1);

    HSSFCell cell2 = row.createCell((short)2);

 

    HSSFCellStyle style1 = workbook.createCellStyle();

    style1.setBorderTop(HSSFCellStyle.BORDER_DOUBLE);

    style1.setBorderLeft(HSSFCellStyle.BORDER_DOUBLE);

    style1.setTopBorderColor(HSSFColor.GOLD.index);

    style1.setLeftBorderColor(HSSFColor.PLUM.index);

    cell1.setCellStyle(style1);

 

    HSSFCellStyle style2 = workbook.createCellStyle();

    style2.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);

    style2.setBorderRight(HSSFCellStyle.BORDER_DOUBLE);

    style2.setBottomBorderColor(HSSFColor.ORANGE.index);

    style2.setRightBorderColor(HSSFColor.SKY_BLUE.index);

    cell2.setCellStyle(style2);

 

    cell1.setCellValue("U & L");

    cell2.setCellValue("B & R");

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

}

上面程序既改了顔色,也设置了上和左的边框各一个,右和下的边框各一个。

 

下面再对边框种类进行各种各样的顔色改变来看看效果。

import java.io.*;

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

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

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

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

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

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

 

public class POISample{

  static HSSFWorkbook workbook;

 

  public static void main(String[] args){

    workbook = new HSSFWorkbook();

 

    HSSFSheet sheet = workbook.createSheet();

 

    HSSFRow row[] = new HSSFRow[5];

    for (int i = 0; i < 5 ; i++){

      row[i] = sheet.createRow(i);

    }

 

    HSSFCell cell[][] = new HSSFCell[5][3];

    for (int i = 0; i < 5; i++){

      for (int j = 0; j < 3 ; j++){

        cell[i][j] = row[i].createCell((short)j);

      }

    }

 

    setStyle(cell[0][0], "DASH_DOT",

                          HSSFCellStyle.BORDER_DASH_DOT);

    setStyle(cell[0][1], "DASH_DOT_DOT",

                          HSSFCellStyle.BORDER_DASH_DOT_DOT);

    setStyle(cell[0][2], "DASHED",

                          HSSFCellStyle.BORDER_DASHED);

 

    setStyle(cell[1][0], "DOTTED",

                          HSSFCellStyle.BORDER_DOTTED);

    setStyle(cell[1][1], "DOUBLE",

                          HSSFCellStyle.BORDER_DOUBLE);

    setStyle(cell[1][2], "HAIR",

                          HSSFCellStyle.BORDER_HAIR);

 

    setStyle(cell[2][0], "MEDIUM",

                          HSSFCellStyle.BORDER_MEDIUM);

    setStyle(cell[2][1], "MEDIUM_DASH_DOT",

                          HSSFCellStyle.BORDER_MEDIUM_DASH_DOT);

    setStyle(cell[2][2], "MEDIUM_DASH_DOT_DOT",

                          HSSFCellStyle.BORDER_MEDIUM_DASH_DOT_DOT);

 

    setStyle(cell[3][0], "MEDIUM_DASHED",

                          HSSFCellStyle.BORDER_MEDIUM_DASHED);

    setStyle(cell[3][1], "NONE",

                          HSSFCellStyle.BORDER_NONE);

    setStyle(cell[3][2], "SLANTED_DASH_DOT",

                          HSSFCellStyle.BORDER_SLANTED_DASH_DOT);

 

    setStyle(cell[4][0], "THICK", HSSFCellStyle.BORDER_THICK);

    setStyle(cell[4][1], "THIN", HSSFCellStyle.BORDER_THIN);

 

    FileOutputStream out = null;

    try{

      out = new FileOutputStream("sample.xls");

      workbook.write(out);

    }catch(IOException e){

      System.out.println(e.toString());

    }finally{

      try {

        out.close();

      }catch(IOException e){

        System.out.println(e.toString());

      }

    }

  }

 

  public static void setStyle(HSSFCell cell,

                          String bn, short border){

    HSSFCellStyle style = workbook.createCellStyle();

    style.setBorderBottom(border);

    style.setBottomBorderColor(HSSFColor.ORANGE.index);

    cell.setCellStyle(style);

 

    cell.setCellValue(bn);

  }

}

运行结果如下:

 

 

 

 

 

 

==========================================异常华丽的分割线=============================================================

poi使用整理总结_第1张图片poi使用整理总结_第2张图片poi使用整理总结_第3张图片poi使用整理总结_第4张图片poi使用整理总结_第5张图片poi使用整理总结_第6张图片poi使用整理总结_第7张图片poi使用整理总结_第8张图片poi使用整理总结_第9张图片poi使用整理总结_第10张图片poi使用整理总结_第11张图片poi使用整理总结_第12张图片poi使用整理总结_第13张图片poi使用整理总结_第14张图片poi使用整理总结_第15张图片poi使用整理总结_第16张图片poi使用整理总结_第17张图片poi使用整理总结_第18张图片poi使用整理总结_第19张图片poi使用整理总结_第20张图片poi使用整理总结_第21张图片poi使用整理总结_第22张图片poi使用整理总结_第23张图片poi使用整理总结_第24张图片poi使用整理总结_第25张图片poi使用整理总结_第26张图片poi使用整理总结_第27张图片poi使用整理总结_第28张图片poi使用整理总结_第29张图片poi使用整理总结_第30张图片poi使用整理总结_第31张图片poi使用整理总结_第32张图片poi使用整理总结_第33张图片poi使用整理总结_第34张图片poi使用整理总结_第35张图片poi使用整理总结_第36张图片poi使用整理总结_第37张图片poi使用整理总结_第38张图片poi使用整理总结_第39张图片poi使用整理总结_第40张图片poi使用整理总结_第41张图片poi使用整理总结_第42张图片poi使用整理总结_第43张图片poi使用整理总结_第44张图片poi使用整理总结_第45张图片poi使用整理总结_第46张图片poi使用整理总结_第47张图片poi使用整理总结_第48张图片poi使用整理总结_第49张图片poi使用整理总结_第50张图片poi使用整理总结_第51张图片poi使用整理总结_第52张图片poi使用整理总结_第53张图片poi使用整理总结_第54张图片poi使用整理总结_第55张图片poi使用整理总结_第56张图片poi使用整理总结_第57张图片poi使用整理总结_第58张图片poi使用整理总结_第59张图片poi使用整理总结_第60张图片poi使用整理总结_第61张图片poi使用整理总结_第62张图片poi使用整理总结_第63张图片poi使用整理总结_第64张图片poi使用整理总结_第65张图片poi使用整理总结_第66张图片

添加 POI 支持 
 
鉴于现在大部分应用是以 Maven 作为构建,可在 pom.xml 中加入 POI 的 maven 依赖,但是 maven 现在只支持到 3.1 版本,对 3.5 版本还不提供支持。 poi    poi    3.1-FINAL  
 
因此可以直接在 Apache 官网下载 POI3.5 版本,作为 reference library 加入 工程中 
创建新工作簿 Workbook wb = new HSSFWorkbook();     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close(); 
 
    Workbook wb = new XSSFWorkbook(); FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");     wb.write(fileOut); fileOut.close(); 
 
创建新 sheet 页     Workbook wb = new HSSFWorkbook();     //Workbook wb = new XSSFWorkbook();     Sheet sheet1 = wb.createSheet("new sheet");     Sheet sheet2 = wb.createSheet("second sheet");     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close(); 
 
创建单元格     Workbook wb = new HSSFWorkbook();     //Workbook wb = new XSSFWorkbook();     CreationHelper createHelper = wb.getCreationHelper();     Sheet sheet = wb.createSheet("new sheet"); 
 
//创建一列,在其中加入多个单元格,列索引号从 0 开始,单元格的索引号也是从 0 //开始 
POI3.5 HSSF&XSSF Excel 操作快速入门 

本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    Row row = sheet.createRow((short)0);1     //创建一个单元格,并在其中加入内容.     Cell cell = row.createCell(0);     cell.setCellValue(1); 
 
    // 上面的多行代码可以采用下面的一行代码的方式完成     row.createCell(1).setCellValue(1.2);     row.createCell(2).setCellValue(          createHelper.createRichTextString("This is a string"));     row.createCell(3).setCellValue(true); 
 
    //将输出流写入一个文件     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close();                      
新建一个时间格式的单元格     //Workbook wb = new XSSFWorkbook();     CreationHelper createHelper = wb.getCreationHelper();     Sheet sheet = wb.createSheet("new sheet"); 
 
   //创建一列,在其中加入多个单元格,列索引号从 0 开始,单元格的索引号也是从 0 //开始     Row row = sheet.createRow(0); 
 
    //创建一个单元格,并在其中加入内容.  第一个单元格的内容不设置为日期时间格式     Cell cell = row.createCell(0);     cell.setCellValue(new Date()); 
 
//我们将第二个单元格设置成日期(和时间)格式。对这个文件来说创建一个新的单 //元格格式非常重要,除非您能够不用内置的格式来渲染所有的单元格     CellStyle cellStyle = wb.createCellStyle();     cellStyle.setDataFormat(     createHelper.createDataFormat().getFormat("m/d/yy h:mm"));     cell = row.createCell(1);     cell.setCellValue(new Date());     cell.setCellStyle(cellStyle); 
 
    //也可以用 java.util.Calendar 来设置单元格格式      cell = row.createCell(2);     cell.setCellValue(Calendar.getInstance()); 
                                                             1 很多方法的参数是 short 而不是 int 所以需要做一次类型转换  --译者注 
POI3.5 HSSF&XSSF Excel 操作快速入门 

本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    cell.setCellStyle(cellStyle); 
 
    // 将输出流写入一个文件     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut); fileOut.close(); 
 
处理不同内容格式的单元格     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("new sheet");     Row row = sheet.createRow((short)2);     row.createCell(0).setCellValue(1.1);     row.createCell(1).setCellValue(new Date());     row.createCell(2).setCellValue(Calendar.getInstance());     row.createCell(3).setCellValue("a string");     row.createCell(4).setCellValue(true);     row.createCell(5).setCellType(HSSFCell.CELL_TYPE_ERROR); 
 
    //将输出流写入一个文件     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut); fileOut.close(); 
 
遍历列和单元格  有些时候您仅希望遍历一个 sheet 页中所有的列或是一列中所有的单元格。这可以用 一个简单的 for 循环来实现。 
 幸运的是,这非常简单。Row 对象定义了一个 CellIterator 内部类用来处理单元格的 遍历(可以通过调用 row.cellIterator() 来获得 Iterator 对象),另外,Sheet 对象提供 了一个 rowIterator()方法对所有列进行遍历 
 除此之外,Sheet 和 Row 对象都实现了 java.lang.Iterable 接口,因此如果您用的 是 Java 1.5 及以上版本,您可以简单的调用内置的“foreach”来实现。请看: 
 Sheet sheet = wb.getSheetAt(0);  for (Iterator rit = sheet.rowIterator(); rit.hasNext(); ) {   Row row = rit.next();   for (Iterator cit = row.cellIterator(); cit.hasNext(); ) {    Cell cell = cit.next();    // Do something here   } 
POI3.5 HSSF&XSSF Excel 操作快速入门 

本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
 } 使用 J ava1.5 foreach 循环遍历列和单元格 
有时候您仅希望遍历一个 sheet 页中所有的列或是一列中所有的单元格。如果您使用的是 java1.5 或是以上版本,那么这将十分的方便,因为它支持新的 foreach 循环。 
幸运的是,这非常的简单。Sheet 和 Row 对象都实现了 java.lang.Iterable 接口支持 foreach 循环。对 Row 对象来说它支持通过调用 CellIterator 内部类用来处理单元格的 遍历,对于 Sheet 对象来说它提供了一个 rowIterator()方法对所有列进行遍历。 
 Sheet sheet = wb.getSheetAt(0);  for (Row row : sheet) {   for (Cell cell : row) {    // Do something here   }  } 
 
获得单元格内的内容 
要想获得单元格内的内容,您首先要要知道单元格内容的格式(比如您想获得从字符 格式的单元格内获得一个数字,您将得到的是 NumberFormatException 错误)。因此, 您将希望能够切换到该单元格格式,然后为获得该单元格内容调用合适的 getter 方法。 
在以下的代码中我们将对一个 sheet 页中的所有单元格进行遍历,并打印出单元格的引用 和内容。 
// import org.apache.poi.ss.usermodel.*; 
 
Sheet sheet1 = wb.getSheetAt(0); for (Row row : sheet1) {  for (Cell cell : row) {   CellReference cellRef = new CellReference(row.getRowNum(), cell.getCellNum());   System.out.print(cellRef.formatAsString());   System.out.print(" - ");      switch(cell.getCellType()) {       case Cell.CELL_TYPE_STRING:         System.out.println(cell.getRichStringCellValue().getString());         break;       case Cell.CELL_TYPE_NUMERIC:         if(DateUtil.isCellDateFormatted(cell)) {           System.out.println(cell.getDateCellValue());         } else {           System.out.println(cell.getNumericCellValue()); 
POI3.5 HSSF&XSSF Excel 操作快速入门 

本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
        }         break;       case Cell.CELL_TYPE_BOOLEAN:         System.out.println(cell.getBooleanCellValue());         break;       case Cell.CELL_TYPE_FORMULA:         System.out.println(cell.getCellFormula());         break;       default:         System.out.println();   }  } } 
 
文本提取 
对于大多数的文本提取需求,标准的 ExcelExtractor 类应该能够满足您所有的需求。 
 InputStream inp = new FileInputStream("workbook.xls");  HSSFWorkbook wb = new HSSFWorkbook(new POIFSFileSystem(inp));  ExcelExtractor extractor = new ExcelExtractor(wb); 
 
 extractor.setFormulasNotResults(true);  extractor.setIncludeSheetNames(false);  String text = extractor.getText(); 
对于特殊的文本提取,比如将 xls 文件内容写入 csv 文件,可以参考: /src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSV mra.java 文件 
单元格的各种对齐方式     public static void main(String[] args)  throws Exception {         Workbook wb = new XSSFWorkbook(); //或者是 new HSSFWorkbook(); 
 
        Sheet sheet = wb.createSheet();         Row row = sheet.createRow((short) 2);         row.setHeightInPoints(30); 
 
        createCell(wb, row, (short) 0, XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_BOTTOM);         createCell(wb, row, (short) 1, XSSFCellStyle.ALIGN_CENTER_SELECTION, XSSFCellStyle.VERTICAL_BOTTOM);         createCell(wb, row, (short) 2, XSSFCellStyle.ALIGN_FILL, XSSFCellStyle.VERTICAL_CENTER); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
10 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
        createCell(wb, row, (short) 3, XSSFCellStyle.ALIGN_GENERAL, XSSFCellStyle.VERTICAL_CENTER);         createCell(wb, row, (short) 4, XSSFCellStyle.ALIGN_JUSTIFY, XSSFCellStyle.VERTICAL_JUSTIFY);         createCell(wb, row, (short) 5, XSSFCellStyle.ALIGN_LEFT, XSSFCellStyle.VERTICAL_TOP);         createCell(wb, row, (short) 6, XSSFCellStyle.ALIGN_RIGHT, XSSFCellStyle.VERTICAL_TOP); 
 
        //将输出流写入一个文件         FileOutputStream fileOut = new FileOutputStream("xssf-align.xlsx");         wb.write(fileOut);         fileOut.close(); 
 
    } 
 
    /**      *创建一个单元格并为其设定指定的对齐方式.      *      * @param wb       工作簿      * @param row     单元格所在的列      * @param column 单元格所在的行索引号      * @param halign 单元格的水平对齐方式.      */     private static void createCell(Workbook wb, Row row, short column, short halign, short valign) {         Cell cell = row.createCell(column);         cell.setCellValue(new XSSFRichTextString("Align It"));         CellStyle cellStyle = wb.createCellStyle();         cellStyle.setAlignment(halign);         cellStyle.setVerticalAlignment(valign);         cell.setCellStyle(cellStyle);     }                      
如何处理边框     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("new sheet"); 
 
   //创建一列,在其中加入多个单元格,列索引号从 0 开始,单元格的索引号也是从 0 //开始.     Row row = sheet.createRow(1); 
 
POI3.5 HSSF&XSSF Excel 操作快速入门 
11 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    //创建一个单元格,并在其中加入内容.     Cell cell = row.createCell(1);     cell.setCellValue(4); 
 
    //设置单元格边框为四周环绕.     CellStyle style = wb.createCellStyle();     style.setBorderBottom(CellStyle.BORDER_THIN);     style.setBottomBorderColor(IndexedColors.BLACK.getIndex());     style.setBorderLeft(CellStyle.BORDER_THIN);     style.setLeftBorderColor(IndexedColors.GREEN.getIndex());     style.setBorderRight(CellStyle.BORDER_THIN);     style.setRightBorderColor(IndexedColors.BLUE.getIndex());     style.setBorderTop(CellStyle.BORDER_MEDIUM_DASHED);     style.setTopBorderColor(IndexedColors.BLACK.getIndex());     cell.setCellStyle(style); 
 
    //将输出流写入一个文件     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close(); 
 
填充色和颜色操作 Workbook wb = new XSSFWorkbook();     Sheet sheet = wb.createSheet("new sheet"); 
 
   //创建一列,在其中加入多个单元格,列索引号从 0 开始,单元格的索引号也是从 0 //开始     Row row = sheet.createRow((short) 1); 
 
    // 浅绿色背景色     CellStyle style = wb.createCellStyle();     style.setFillBackgroundColor(IndexedColors.AQUA.getIndex());     style.setFillPattern(CellStyle.BIG_SPOTS);     Cell cell = row.createCell((short) 1);     cell.setCellValue("X");     cell.setCellStyle(style); 
 
    //橙色前景色。前景色:前景色是指正在使用的填充颜色,而非字体颜色     style = wb.createCellStyle();     style.setFillForegroundColor(IndexedColors.ORANGE.getIndex());     style.setFillPattern(CellStyle.SOLID_FOREGROUND);     cell = row.createCell((short) 2);     cell.setCellValue("X"); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
12 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    cell.setCellStyle(style); 
 
    //将输出流写入一个文件     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut); fileOut.close(); 
 
合并单元格     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("new sheet"); 
 
    Row row = sheet.createRow((short) 1);     Cell cell = row.createCell((short) 1);     cell.setCellValue("This is a test of merging"); 
 
    sheet.addMergedRegion(new CellRangeAddress(             1, //first row (0-based)             1, //last row  (0-based)             1, //first column (0-based)             2  //last column  (0-based)     )); 
 
    //将输出流写入一个文件     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close(); 
 
字体的处理     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("new sheet"); 
 
   //创建一列,在其中加入多个单元格,列索引号从 0 开始,单元格的索引号也是从 0 //开始     Row row = sheet.createRow(1); 
 
    // 创建一个字体并修改它的样式.     Font font = wb.createFont();     font.setFontHeightInPoints((short)24);     font.setFontName("Courier New");     font.setItalic(true);     font.setStrikeout(true); 
 
POI3.5 HSSF&XSSF Excel 操作快速入门 
13 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
//字体在样式(style)中载入才能使用,因此创建一个 style 来使用该字体     CellStyle style = wb.createCellStyle();     style.setFont(font); 
 
    //创建一个单元格,并在其中加入内容.     Cell cell = row.createCell(1);     cell.setCellValue("This is a test of fonts");     cell.setCellStyle(style); 
 
    //将输出流写入一个文件     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close();    注意:  一个工作簿中最大的自定义字体数目为 32767(short 类型最大正数)。您应当复用这些字 体,而不是为每一个单元格新建一个字体。比如:  
错误的用法:  
        for (int i = 0; i < 10000; i++) {             Row row = sheet.createRow(i);             Cell cell = row.createCell((short) 0); 
 
            CellStyle style = workbook.createCellStyle();             Font font = workbook.createFont();             font.setBoldweight(Font.BOLDWEIGHT_BOLD);             style.setFont(font);             cell.setCellStyle(style);         } 
正确的用法 :  
        CellStyle style = workbook.createCellStyle();         Font font = workbook.createFont();         font.setBoldweight(Font.BOLDWEIGHT_BOLD);         style.setFont(font);         for (int i = 0; i < 10000; i++) {             Row row = sheet.createRow(i);             Cell cell = row.createCell((short) 0);             cell.setCellStyle(style);         } 
 
POI3.5 HSSF&XSSF Excel 操作快速入门 
14 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
自定义颜色 
HSSF:  
    HSSFWorkbook wb = new HSSFWorkbook();     HSSFSheet sheet = wb.createSheet();     HSSFRow row = sheet.createRow((short) 0);     HSSFCell cell = row.createCell((short) 0);     cell.setCellValue("Default Palette"); 
 
//就像上面一个例子一样从标准调色板上获得几种颜色 //我们将在石灰色的背景上应用红色字体 
 
    HSSFCellStyle style = wb.createCellStyle();     style.setFillForegroundColor(HSSFColor.LIME.index);     style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); 
 
    HSSFFont font = wb.createFont();     font.setColor(HSSFColor.RED.index);     style.setFont(font); 
 
    cell.setCellStyle(style); 
 
    //替换保存为默认调色板     FileOutputStream out = new FileOutputStream("default_palette.xls");     wb.write(out);     out.close(); 
 
    //现在然我们把橙色和石灰色的组合替换成更有吸引力的组合     // 还是比较喜欢 freebsd.org 提供的色彩方案 
 
    cell.setCellValue("Modified Palette"); 
 
    //为该工作簿新建一个调色板     HSSFPalette palette = wb.getCustomPalette(); 
 
    //替换标准红色为 freebsd.org 上的红色     palette.setColorAtIndex(HSSFColor.RED.index,             (byte) 153,  //RGB red (0-255)             (byte) 0,    //RGB green             (byte) 0     //RGB blue     );     //替换石灰色为 freebsd.org 上的金色 
POI3.5 HSSF&XSSF Excel 操作快速入门 
15 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    palette.setColorAtIndex(HSSFColor.LIME.index, (byte) 255, (byte) 204, (byte) 102); 
 
    //将其保存为“修改过的调色板”     // 注意,不论我们以前在哪里用到了红色和石灰色,都会奇迹般的换上现在的颜色     out = new FileOutputStream("modified_palette.xls");     wb.write(out);     out.close();                      
XSSF:  
    XSSFWorkbook wb = new XSSFWorkbook();     XSSFSheet sheet = wb.createSheet();     XSSFRow row = sheet.createRow(0);     XSSFCell cell = row.createCell( 0);     cell.setCellValue("custom XSSF colors"); 
 
    XSSFCellStyle style1 = wb.createCellStyle();     style1.setFillForegroundColor(new XSSFColor(new java.awt.Color(128, 0, 128)));     style1.setFillPattern(CellStyle.SOLID_FOREGROUND);                      
读取和重写工作簿     InputStream inp = new FileInputStream("workbook.xls");     //InputStream inp = new FileInputStream("workbook.xlsx"); 
 
    Workbook wb = WorkbookFactory.create(inp);     Sheet sheet = wb.getSheetAt(0);     Row row = sheet.getRow(2);     Cell cell = row.getCell(3);     if (cell == null)         cell = row.createCell(3);     cell.setCellType(Cell.CELL_TYPE_STRING);     cell.setCellValue("a test"); 
 
    //将输出流写入一个文件     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close();                      
在单元格中使用换行     Workbook wb = new XSSFWorkbook();   //or new HSSFWorkbook(); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
16 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    Sheet sheet = wb.createSheet(); 
 
    Row row = sheet.createRow(2);     Cell cell = row.createCell(2);     cell.setCellValue("Use \n with word wrap on to create a new line"); 
 
    //为了能够使用换行,您需要设置单元格的样式 wrap=true     CellStyle cs = wb.createCellStyle();     cs.setWrapText(true);     cell.setCellStyle(cs); 
 
    //增加单元格的高度已能够容纳两行文字     row.setHeightInPoints((2*sheet.getDefaultRowHeightInPoints())); 
 
    // 调整列宽以使用内容长度     sheet.autoSizeColumn((short)2); 
 
    FileOutputStream fileOut = new FileOutputStream("ooxml-newlines.xlsx");     wb.write(fileOut);     fileOut.close();                    
创建用户自定义数据格式     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("format sheet");     CellStyle style;     DataFormat format = wb.createDataFormat();     Row row;     Cell cell;     short rowNum = 0;     short colNum = 0; 
 
    row = sheet.createRow(rowNum++);     cell = row.createCell(colNum);     cell.setCellValue(11111.25);     style = wb.createCellStyle();     style.setDataFormat(format.getFormat("0.0"));     cell.setCellStyle(style); 
 
    row = sheet.createRow(rowNum++);     cell = row.createCell(colNum);     cell.setCellValue(11111.25); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
17 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    style = wb.createCellStyle();     style.setDataFormat(format.getFormat("#,##0.0000"));     cell.setCellStyle(style); 
 
    FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close();                      
Sheet 页自适应页面大小     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("format sheet");     PrintSetup ps = sheet.getPrintSetup(); 
 
    sheet.setAutobreaks(true); 
 
    ps.setFitHeight((short)1);     ps.setFitWidth((short)1); 
 
 
//为电子表格创建多行多列.  。。。。。。。     FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close();                      
设定打印区域     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("Sheet1");     //为第一个 sheet 页设定打印区域     wb.setPrintArea(0, "$A$1:$C$2");          //也可以这样实现:     wb.setPrintArea(             0, //sheet 页标             0, //开始列标             1, //结束列标             0, //开始行标             0  //结束行标     ); 
 
    FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
18 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    fileOut.close();                      
设置脚注页码     HSSFWorkbook wb = new HSSFWorkbook();     HSSFSheet sheet = wb.createSheet("format sheet");     HSSFFooter footer = sheet.getFooter() 
 
    footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() ); 
 
 
//为电子表格创建多行多列 。。。。。。 
 
    FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close(); 
 
使用便捷函数 
便捷函数存在于 contrib2中,并提供许多实用功能如不用明确的新建一个样式就能够为合 并区域设置边框和改变样式。 
    HSSFWorkbook wb = new HSSFWorkbook();     HSSFSheet sheet1 = wb.createSheet( "new sheet" ); 
 
    //创建一个合并区域     HSSFRow row = sheet1.createRow( (short) 1 );     HSSFRow row2 = sheet1.createRow( (short) 2 );     HSSFCell cell = row.createCell( (short) 1 );     cell.setCellValue( "This is a test of merging" );     Region region = new Region( 1, (short) 1, 4, (short) 4 );     sheet1.addMergedRegion( region ); 
 
    // 设置边框和边框颜色     final short borderMediumDashed = HSSFCellStyle.BORDER_MEDIUM_DASHED;     HSSFRegionUtil.setBorderBottom( borderMediumDashed,         region, sheet1, wb );     HSSFRegionUtil.setBorderTop( borderMediumDashed,         region, sheet1, wb ); 
                                                             2Contrib:外围爱好者根据需要自行编译并贡献的软件 —译者注 
POI3.5 HSSF&XSSF Excel 操作快速入门 
19 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    HSSFRegionUtil.setBorderLeft( borderMediumDashed,         region, sheet1, wb );     HSSFRegionUtil.setBorderRight( borderMediumDashed,         region, sheet1, wb );     HSSFRegionUtil.setBottomBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);     HSSFRegionUtil.setTopBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);     HSSFRegionUtil.setLeftBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);     HSSFRegionUtil.setRightBorderColor(HSSFColor.AQUA.index, region, sheet1, wb); 
 
    //展示 HSSFCellUtil 的一些用法     HSSFCellStyle style = wb.createCellStyle();     style.setIndention((short)4);     HSSFCellUtil.createCell(row, 8, "This is the value of the cell", style);     HSSFCell cell2 = HSSFCellUtil.createCell( row2, 8, "This is the value of the cell");     HSSFCellUtil.setAlignment(cell2, wb, HSSFCellStyle.ALIGN_CENTER); 
 
    //输出工作簿     FileOutputStream fileOut = new FileOutputStream( "workbook.xls" );     wb.write( fileOut );     fileOut.close();                      
上下移动一行         Workbook wb = new HSSFWorkbook();         Sheet sheet = wb.createSheet("row sheet"); 
 
      //为电子表格创建多行多列  。。。。。。       // 将第 6 到 第 11 行移至顶端 第 0 到 第 5 行         sheet.shiftRows(5, 10, -5); 
 
将 sheet 页设定为默认选中     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("row sheet");     sheet.setSelected(true); 
 
POI3.5 HSSF&XSSF Excel 操作快速入门 
20 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
设置 sheet 页放大倍率 
放大倍率是用分数来表示的,比如,如果放大倍率是 75%,那么可以用 3/4 来表示 
    Workbook wb = new HSSFWorkbook();     Sheet sheet1 = wb.createSheet("new sheet");     sheet1.setZoom(3,4);   // 75%放大倍率 
 
拆分和冻结窗格 
您可以创建两种窗格:冻结窗格和拆分窗格 
冻结窗格是由行和列来分隔的。您可以采用以下的方式来创建冻结窗格: 
sheet1.createFreezePane( 3, 2, 3, 2 ); 3 
The first two parameters are the columns and rows you wish to split by. The second two parameters indicate the cells that are visible in the bottom right quadrant.  
前两个参数是您想分隔开的列数和行数,后两个参数表示在右下部分中可见的单元格。其 中第三个参数是右边区域可见的左边列数,第四个参数是下面区域可见的首行。 
拆分窗格看起来和冻结窗格很不一样。拆分窗格被分成了 4 个单独的工作区域。拆分是像 素级别的,用户可以通过改变拆分点来调整拆分的效果。 
拆分窗格可以通过调用以下方法实现: 
sheet2.createSplitPane( 2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT );  
第一个参数是拆分点在 X 轴上的坐标。单位是 1/20 个点。在这里可以把一个点看成一个 像素。第二个参数是拆分点在 Y 轴上的坐标,单位同样也是 1/20 个点。第三个参数是右边 区域可见的左边列数,第四个参数是下面区域可见的首行 
最后一个参数指定了该拆分点落在了哪个窗格中。一共有四种选项 Sheet.PANE_LOWER_LEFT, PANE_LOWER_RIGHT, PANE_UPPER_RIGHT 或者 PANE_UPPER_LEFT.  
    Workbook wb = new HSSFWorkbook();     Sheet sheet1 = wb.createSheet("new sheet");     Sheet sheet2 = wb.createSheet("second sheet");     Sheet sheet3 = wb.createSheet("third sheet");     Sheet sheet4 = wb.createSheet("fourth sheet"); 
 
    // 冻结第一行     sheet1.createFreezePane( 0, 1, 0, 1 ); 
                                                             3 createFreezePane 方法有两种 createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) 和 createFreezePane(int colSplit, int rowSplit) 在冻结整行整列时第二种方法更为简便 –译者注 
POI3.5 HSSF&XSSF Excel 操作快速入门 
21 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    // 冻结第一列     sheet2.createFreezePane( 1, 0, 1, 0 );     //冻结列和行(这里可以忽略右下方的滚动条的位置)     sheet3.createFreezePane( 2, 2 );     //拆分窗口并且使左下方有焦点     sheet4.createSplitPane( 2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT ); 
 
    FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close();                      
重复列和行  
在打印时,可以通过 HSSFWorkbook 类的 setRepeatingRowsAndColumns()方法设 置重复的列和行。  
这个方法包含五个参数。第一个参数是 sheet 页的索引(0 代表第一个 sheet 页)。第二 和第三个参数指定了重复列的范围,如果不想重复列的话,可以用-1 代替。第四和第五 个参数指定了重复行的范围,同样如果不想重复行可以用-1 替代起止索引号。 
    Workbook wb = new HSSFWorkbook();     Sheet sheet1 = wb.createSheet("new sheet");     Sheet sheet2 = wb.createSheet("second sheet"); 
 
 //设置第一张 sheet 页中的第一到第三列重复     wb.setRepeatingRowsAndColumns(0,0,2,-1,-1);     // 为第二张 sheet 页设置重复列和行     wb.setRepeatingRowsAndColumns(1,4,5,1,2); 
 
    FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close();                      
页眉和页脚 
这是一个页眉的例子,但页脚也同样适用 
    Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet("new sheet"); 
 
    Header header = sheet.getHeader();     header.setCenter("Center Header");     header.setLeft("Left Header");     header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") + 
POI3.5 HSSF&XSSF Excel 操作快速入门 
22 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
                    HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16"); 
 
    FileOutputStream fileOut = new FileOutputStream("workbook.xls");     wb.write(fileOut);     fileOut.close();                      
绘制图形  
POI 支持调用 MS-Office 绘图工具进行图形的绘制。一张 sheet 页上的图形是按照有层 级的图形组和图形来安排的。最顶层的图形是 patriarch,它在 sheet 页上是不可见的。 在开始绘制图形之前,您需要在 HSSFSheet 对象中调用 createPatriarch 方法。调 用这个方法会清除在该 sheet 页中储存的所有的图形信息。默认情况下只要这个方法不 被调用,POI 不会将图形数据清除。 
要创建一个图形,您需要做以下几步: 
1. 创建一个 patriarch 对象 
2. 创建一个锚点以供图形在 sheet 页上定位 
3. 调用 patriarch 对象创建一个图形 
4. 设置图形类型(直线,椭圆,矩形等等) 
5. 设置图形的其他样式细节(例如:线条粗细等等) 
    HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); 
    a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 );     HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);     shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);                      
文本框的创建方式如下:
 
    HSSFTextbox textbox1 = patriarch.createTextbox(             new HSSFClientAnchor(0,0,0,0,(short)1,1,(short)2,2));     textbox1.setString(new HSSFRichTextString("This is a test") );                      
在同一文本框中设置不同的字体样式也是可以实现的
 
    HSSFFont font = wb.createFont();     font.setItalic(true);     font.setUnderline(HSSFFont.U_DOUBLE);     HSSFRichTextString string = new HSSFRichTextString("Woo!!!"); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
23 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    string.applyFont(2,5,font);     textbox.setString(string );                      
Just as can be done manually using Excel, it is possible to group shapes together. This is done by calling createGroup() and then creating the shapes using those groups.  
如同 Excel 中可以手动设置组一样,调用 createGroup()方法,用新建的组创建图形 也可以实现。组中也可以嵌套其他组。 
注意 
任何一个组中必须至少包含两个不同图形或是其他的子组。 
 
创建图片组可以参考下面的例子:      // 创建一个图片组. HSSFShapeGroup group = patriarch.createGroup( new HSSFClientAnchor(0,0,900,200,(short)2,2,(short)2,2)); 
 
    //在图片组中创建多条直线.     HSSFSimpleShape shape1 = group.createShape(new HSSFChildAnchor(3,3,500,500));     shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);     ( (HSSFChildAnchor) shape1.getAnchor() ).setAnchor((short)3,3,500,500);     HSSFSimpleShape shape2 = group.createShape(new HSSFChildAnchor((short)1,200,400,600));     shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);                      
如果您足够细心,您将会发下,在图形组中添加的图形使用的是一个新类型的锚点对象 HSSFChildAnchor。这是因为新创建的组会有自己的坐标空间。在 POI 中,这个 坐标 空间默认为(0,0,1023,255),但是您也可以根据自己的意愿进行修改。 
    myGroup.setCoordinates(10,10,20,20); // top-left, bottom-right                      
如果您在一个图片组中加入了另外一个图片组,同样该子图片组也有自己的坐标空间。 
 
设置图形样式 
默认的图片演示看起来有些平常。为图形设置不同的样式也可以通过 POI 来实现。不过现 在仅能支持以下几种图形样式改变: 
 变换填充色 
POI3.5 HSSF&XSSF Excel 操作快速入门 
24 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
 去除填充色 
 改变线条粗细 
 改变线条样式 比如:虚线,点线等等 
 改变线条颜色 
以下是如何实现  
    HSSFSimpleShape s = patriarch.createSimpleShape(a);     s.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);     s.setLineStyleColor(10,10,10);     s.setFillColor(90,10,200);     s.setLineWidth(HSSFShape.LINEWIDTH_ONE_PT * 3);     s.setLineStyle(HSSFShape.LINESTYLE_DOTSYS);                      
图形和 Graphics2d 类 
虽然推荐使用本地 POI 命名来创建图形,但有时我们也希望调用标准 AIP 获得和外部库 的兼容性。处于这目的我们对 Graphics 和 Graphics2d 类进行了扩充。 
注意: 
在开始使用之前,您需要知道 Graphics2d 对 MS-office 绘图命令的支持不是很好,虽 然 Graphics 类比起来对 MS-office 绘图命令更加兼容,但仍然差强人意。 
所有的绘图指令都封装在 HSSFShapeGroup 类中。以下是它们的用法:  
    a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 );     group = patriarch.createGroup( a );     group.setCoordinates( 0, 0, 80 * 4 , 12 * 23  );     float verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / (float)Math.abs(group.getY2() - group.getY1());     g = new EscherGraphics( group, wb, Color.black, verticalPointsPerPixel );     g2d = new EscherGraphics2d( g );     drawChemicalStructure( g2d );                      
首先我们做的是为我们将要进行的绘制创建一个组并设置它的坐标。接下来,我们计算出 一个合理的 fontSizeMultipler 创建一个 EscherGraphics 对象。因为我们想得到的是 Graphics2d 对象,所以我们我们新建一个 EscherGraphics2d 对象并把它传入一个创 建好的 Graphics 对 象 中 。 最 后 我 们 会 通 过 一 系 列 流 程 将 它 绘 制 成 一 个 EscherGraphics2d 对象。  
在垂直方向上每个点的像素值还需要再深入说明一下。在将 Graphics 对象调用转化成
POI3.5 HSSF&XSSF Excel 操作快速入门 
25 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
Escher 对象调用中遇到的一个困难是,在 Excel 中没有明确的对绝对位置的像素定义。 在 Excel 中,单元格的宽度是用“字符”宽度,高度是用“点”来度量的。不幸的是,在 Excel 中并没有明确的定义被用来度量的字符的类型。估计是由于 Excel 想在不同的平台 上或是在同一平台上使用不同的字体造成的。  
因为这些限制,我们必须要实现一个标准 verticalPointsPerPixel 用来度量每个垂直方 向点所占的像素。当您调用像是 drawString()这样的方法时,所用到的字体的 verticalPointsPerPixel 度量值必须明确。 
计算 verticalPointsPerPixel 值的公式如下: 
    multipler = groupHeightInPoints / heightOfGroup                      
图形组的高度可以通过简单的计算不同图形边界盒的 Y 轴坐标来得到。 获得图新组的高 度也可以简单的调用以下这个方法: 
 HSSFClientAnchor.getAnchorHeightInPoints().  
许多 Graphic 类支持的方法还没有实现,现在已知实现的方法是: 
 fillRect()  fillOval()  drawString()  drawOval()  drawLine()  clearRect() 
现在还不支持的方法会调用 POI 日志机制返回并记录日志信息(默认为 disabled) 
提纲 
提纲对将不同部分的信息聚合在一起非常重要。它可以用 POI 提供的 API 简单的这样实 现: 
    Workbook wb = new HSSFWorkbook();     Sheet sheet1 = wb.createSheet("new sheet"); 
 
    sheet1.groupRow( 5, 14 );     sheet1.groupRow( 7, 14 );     sheet1.groupRow( 16, 19 ); 
 
    sheet1.groupColumn( (short)4, (short)7 );     sheet1.groupColumn( (short)9, (short)12 );     sheet1.groupColumn( (short)10, (short)11 ); 
 
    FileOutputStream fileOut = new FileOutputStream(filename); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
26 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    wb.write(fileOut);     fileOut.close();                      折叠(或展开)一个提纲,可以用以下的方法:     sheet1.setRowGroupCollapsed( 7, true );     sheet1.setColumnGroupCollapsed( (short)4, true );                      
被选中的行或列必须包含一个已经创建好的组,可以是组内的任意位置。 
 
图像处理 
图像是绘图支持的一部分。提价一张图片可以用最高级别的 Drawing 对象调用 createPicture()。现在支持的图片格式有:  
 PNG  JPG  DIB 
应当值得注意的是任何已经存在的绘图可能会因为您添加一张图片到 sheet 页上而被清 除  
插入图片
     //创建一个新的工作簿     Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); 
 
    //为工作簿添加图片.     InputStream is = new FileInputStream("image1.jpeg");     byte[] bytes = IOUtils.toByteArray(is);     int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);     is.close(); 
 
    CreationHelper helper = wb.getCreationHelper(); 
 
    //创建 sheet 页     Sheet sheet = wb.createSheet(); 
 
    // 创建顶层的 Drawing 对象,它是所有图形和图像的载体     Drawing drawing = sheet.createDrawingPatriarch(); 
 
    //添加一个图片图形     ClientAnchor anchor = helper.createClientAnchor(); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
27 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    //设置图形左上角的位置 //然后调用 Picture 的 resize() 方法,自动关联到新坐标    anchor.setCol1(3);     anchor.setRow1(2);     Picture pict = drawing.createPicture(anchor, pictureIdx); 
 
    //自动关联到新坐标     pict.resize(); 
 
    //保存到工作簿     String file = "picture.xls";     if(wb instanceof XSSFWorkbook) file += "x";     FileOutputStream fileOut = new FileOutputStream(file);     wb.write(fileOut);     fileOut.close();          注意 Picture.resize() 现仅支持 JPEG 和 PNG 格式的图片,其他格式暂不支持 
 
从工作簿中读取图片
       List lst = workbook.getAllPictures();     for (Iterator it = lst.iterator(); it.hasNext(); ) {         PictureData pict = (PictureData)it.next();         String ext = pict.suggestFileExtension();         byte[] data = pict.getData();         if (ext.equals("jpeg")){           FileOutputStream out = new FileOutputStream("pict.jpg");           out.write(data);           out.close();         }     } 
 
关联范围和关联单元格  
关联范围是用一个名字代表一组单元格的方式。关联单元格是关联范围的下一级一组单元 格中的一个。您可以用他们的关联范围创建或是得到对应的单元格。当要处理关联范围时 可 以 用 org.apache.poi.hssf.util.CellReference 和 org.apache.poi.hssf.util.AreaReference 两个类(除了包名不一样外,在 XSSF 和 HSSF 中同样有这两个类) 
创建管理范围 / 关联单元格
 
POI3.5 HSSF&XSSF Excel 操作快速入门 
28 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
    // 准备数据     String sname = "TestSheet", cname = "TestName", cvalue = "TestVal";     Workbook wb = new HSSFWorkbook();     Sheet sheet = wb.createSheet(sname);     sheet.createRow(0).createCell((short) 0).setCellValue(cvalue); 
 
    //1.用空间引用为一个单元格创建关联范围     Name namedCell = wb.createName();     namedCell.setNameName(cname);     String reference = sname+"!A1:A1"; // 空间引用     namedCell.setRefersToFormula(reference); 
 
    // 2.用单元格引用为一个单元格创建关联范围     Name namedCel2 = wb.createName();     namedCel2.setNameName(cname);     String reference = sname+"!A1"; //单元格引用     namedCel2.setRefersToFormula(reference); 
 
    // 3. 用空间引用为一组单元格创建关联范围     Name namedCel3 = wb.createName();     namedCel3.setNameName(cname);     String reference = sname+"!A1:C5"; // 空间引用     namedCel3.setRefersToFormula(reference); 
 
    // 4. 创建关联方程     Name namedCel4 = wb.createName();     namedCel4.setNameName("my_sum");     namedCel4.setRefersToFormula("SUM(sname+!$I$2:$I$6)");              
从关联范围 / 关联单元格读取数据  
    // 准备数据     String cname = "TestName";     Workbook wb = getMyWorkbook(); // 获得工作簿 
 
    //获得关联范围     int namedCellIdx = wb.getNameIndex(cellName);     Name aNamedCell = wb.getNameAt(namedCellIdx); 
 
//在关联范围中获得单元格并检测它的内容     AreaReference aref = new AreaReference(aNamedCell.getRefersToFormula());     CellReference[] crefs = aref.getAllReferencedCells();     for (int i=0; i POI3.5 HSSF&XSSF Excel 操作快速入门 
29 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
        Sheet s = wb.getSheet(crefs[i].getSheetName());         Row r = sheet.getRow(crefs[i].getRow());         Cell c = r.getCell(crefs[i].getCol());         //根据单元格数据格式取出单元格内容。。。。。。.     }              从不连续的关联范围中读取数据     // 准备数据     String cname = "TestName";     Workbook wb = getMyWorkbook(); // retrieve workbook 
 
    // 获得关联范围     // Will be something like "$C$10,$D$12:$D$14";     int namedCellIdx = wb.getNameIndex(cellName);     Name aNamedCell = wb.getNameAt(namedCellIdx); 
 
    //在关联范围中获得单元格并检测它的内容 //将会返回 C10 单元格和 D12 到 D14 单元格的空间引用     AreaReference[] arefs = AreaReference.generateContiguous(aNamedCell.getRefersToFormula()) ;     for (int i=0; i POI3.5 HSSF&XSSF Excel 操作快速入门 
30 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
             
为单元格添加注释  
注释是不同于单元格的内容是附属于或者从属与单元格的富文本。注释的内容是独立于单 元格独自存储的,并且是在绘制对象中展示的(比如一个文本框),因此它既独立于单元 格同时又与单元格紧密联系。 
添加注释
 Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); 
 
    CreationHelper factory = wb.getCreationHelper(); 
 
    Sheet sheet = wb.createSheet();          Cell cell = sheet.createRow(3).createCell(5);     cell.setCellValue("F4");          Drawing drawing = sheet.createDrawingPatriarch(); 
 
    ClientAnchor anchor = factory.createClientAnchor();     Comment comment = drawing.createCellComment(anchor);     RichTextString str = factory.createRichTextString("Hello, World!");     comment.setString(str);     comment.setAuthor("Apache POI");     //将注释注册到单元格     cell.setCellComment(comment); 
 
    String fname = "comment-xssf.xls";     if(wb instanceof XSSFWorkbook) fname += "x";     FileOutputStream out = new FileOutputStream(fname);     wb.write(out);     out.close();          
读取单元格的注释
     Cell cell = sheet.get(3).getColumn((short)1);     Comment comment = cell.getCellComment();     if (comment != null) {       RichTextString str = comment.getString();       String author = comment.getAuthor();     }     //  另外您也可以用 sheet.getCellComment(row, column)来获取内容     comment = sheet.getCellComment(3, 1); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
31 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
 
根据内容调整单元格的宽度 Sheet sheet = workbook.getSheetAt(0);     sheet.autoSizeColumn((short)0); //调整第一列的宽度     sheet.autoSizeColumn((short)1); //调整第二列的宽度          注意: 因为 HSSFSheet.autoSizeColumn 使用 Java2D 类来计算列的宽度,因此在图形环境 (graphical environment)不可用的情况下,调用会报错。如果图形环境不可用的情况 下,您必须告诉 java 您使用的是 headless 模式,请设置以下系统属性:  java.awt.headless=true .  
 
超级链接 
获取超级链接
 Sheet sheet = workbook.getSheetAt(0); 
 
    Cell cell = sheet.getRow(0).getCell((short)0);     Hyperlink link = cell.getHyperlink();     if(link != null){         System.out.println(link.getAddress());     } 
创建超级链接
     Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();     CreationHelper createHelper = wb.getCreationHelper(); 
 
    //设置单元格格式为超级链接     //默认情况下超级链接为下划线、蓝色字体     CellStyle hlink_style = wb.createCellStyle();     Font hlink_font = wb.createFont();     hlink_font.setUnderline(Font.U_SINGLE);     hlink_font.setColor(IndexedColors.BLUE.getIndex());     hlink_style.setFont(hlink_font); 
 
    Cell cell;     Sheet sheet = wb.createSheet("Hyperlinks");     //URL     cell = sheet.createRow(0).createCell((short)0);     cell.setCellValue("URL Link"); 
 
    Hyperlink link = 
POI3.5 HSSF&XSSF Excel 操作快速入门 
32 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
createHelper.createHyperlink(Hyperlink.LINK_URL);     link.setAddress("http://poi.apache.org/");     cell.setHyperlink(link);     cell.setCellStyle(hlink_style); 
 
    //关联到当前目录的文件     cell = sheet.createRow(1).createCell((short)0);     cell.setCellValue("File Link");     link = createHelper.createHyperlink(Hyperlink.LINK_FILE);     link.setAddress("link1.xls");     cell.setHyperlink(link);     cell.setCellStyle(hlink_style); 
 
    //e-mail 关联     cell = sheet.createRow(2).createCell((short)0);     cell.setCellValue("Email Link");     link = createHelper.createHyperlink(Hyperlink.LINK_EMAIL);     //注意:如果邮件主题中存在空格,请保证是按照 URL 格式书写的     link.setAddress("mailto:[email protected]?subject=Hyperlinks");     cell.setHyperlink(link);     cell.setCellStyle(hlink_style); 
 
    //关联到工作簿中的位置 
 
    //创建一个目标 sheet 页和目标单元格     Sheet sheet2 = wb.createSheet("Target Sheet");     sheet2.createRow(0).createCell((short)0).setCellValue("Target Cell"); 
 
    cell = sheet.createRow(3).createCell((short)0);     cell.setCellValue("Worksheet Link");     Hyperlink link2 = createHelper.createHyperlink(Hyperlink.LINK_DOCUMENT);     link2.setAddress("'Target Sheet'!A1");     cell.setHyperlink(link2);     cell.setCellStyle(hlink_style); 
 
    FileOutputStream out = new FileOutputStream("hyperinks.xlsx");     wb.write(out);     out.close();          
POI3.5 HSSF&XSSF Excel 操作快速入门 
33 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
数据验证 
注意: 
最新的 3.5 版本,XSSF 数据流不支持数据验证而且 HSSF 数据流也不支持从 sheet 页 中恢复数据的验证 
检测用户输入是否与预定义的值相悖
 
以下的代码中,见限制用户在 A1 单元格中输入的数值仅为 10,20,30 中的一个 
  HSSFWorkbook workbook = new HSSFWorkbook();   HSSFSheet sheet = workbook.createSheet("Data Validation");   CellRangeAddressList addressList = new CellRangeAddressList(       0, 0, 0, 0);   DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(       new String[]{"10", "20", "30"});   HSSFDataValidation dataValidation = new HSSFDataValidation       (addressList, dvConstraint);   datavalidation.setSuppressDropDownArrow(true);   sheet.addValidationData(dataValidation);          
下拉列表
 
以下的代码将完成相同的功能,但是提供一个下拉列表供用户选择 
  HSSFWorkbook workbook = new HSSFWorkbook();   HSSFSheet sheet = workbook.createSheet("Data Validation");   CellRangeAddressList addressList = new CellRangeAddressList(       0, 0, 0, 0);   DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(       new String[]{"10", "20", "30"});   HSSFDataValidation dataValidation = new HSSFDataValidation       (addressList, dvConstraint);   datavalidation.setSuppressDropDownArrow(false);   sheet.addValidationData(dataValidation);          
错误提示信息  
当用户输入非法值是弹出一个消息窗(Message box)告知用户 
 dataValidation.setErrorStyle(HSSFDataValidation.ErrorStyle.STOP);   dataValidation.createErrorBox("Box Title", "Message Text");          
POI3.5 HSSF&XSSF Excel 操作快速入门 
34 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
替换“Box Title”为您想在消息框标题栏所显示的标题名称,替换“Message Text” 为您的错误提示信息 
提示框( Prompt )  
当需要验证的单元格被选中时弹出提示框(Prompt)提醒用户 
  dataValidation.createPromptBox("Title", "Message Text");   dataValidation.setShowPromptBox(true);          createPromptBox() 中的第一个参数是提示框的标题,第二个参数是提示信息。 DVConstraint 对象的 createExplicitListConstraint() 传 入 的 参 数 可 以 是 表 示 Integer,floating point, date 或是文本的 String 数组。 
高级数据校验
 
对输入的数据进行校验比如输入一个在 10 到 100 之间整型的值可以用 
DVConstraint.createNumericConstraint(int, int, String, String)这个工厂方法 
  dvConstraint = DVConstraint.createNumericConstraint(     DVConstraint.ValidationType.INTEGER,     DVConstraint.OperatorType.BETWEEN, "10", "100");          
如果查阅一下 javaDoc 可以看到其他的校验方法和可以支持的类型。请记住不是所有的 类型都支持校验 。通过两个 String 类型传入的参数可以是公式。“=”是一个公式的标 志。 
  dvConstraint = DVConstraint.createNumericConstraint(     DVConstraint.ValidationType.INTEGER,     DVConstraint.OperatorType.BETWEEN, "=SUM(A1:A3)", "100");          
如果 createNumericConstraint()方法已经被调用,那将不能够创建一个下拉列表。同 时 setSuppressDropDownArrow(false)的调用也将被忽略。 时间和日期的约束可以 通 过 调 用 createDateConstraint(int, String, String, String) 或是 createTimeConstraint(int, String, String)来实现。两者的调用与上面的方法类似, javaDoc 中有很详细的解释。  
用单元格中数据创建数据校验值
 
特 定 的 单 元 格 的 内 容 可 以 为 数据校验提 供 校 验 值 。 DVConstraint.createFormulaListConstraint(String)方法对这种校验方式提供支持。 指定从连续的单元格取得的内容作为校验值可以采用以下两种方法中的一种: 
  dvConstraint = DVConstraint.createFormulaListConstraint("$A$1:$A$3");        
POI3.5 HSSF&XSSF Excel 操作快速入门 
35 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
或者 
  HSSFNamedRange namedRange = workbook.createName();   namedRange.setNameName("list1");   namedRange.setRefersToFormula("$A$1:$A$3");   dvConstraint = DVConstraint.createFormulaListConstraint("list1");        
在上面两个例子中,用户将可以从下拉列表中选择从 A1A2A3 单元格中取到的值。 
所有的数据不一定都是校验值。然而从不同的 sheet 页中取得数据的话,这个 sheet 页 在创建的时候必须别赋予一个 sheet 名,并且这个名字应该在方程式中使用。那么,假设 存在一个名字是“Data Sheet”的 sheet 页,那可以这样操作: 
  HSSFNamedRange namedRange = workbook.createName();   namedRange.setNameName("list1");   namedRange.setRefersToFormula("'Data Sheet'!$A$1:$A$3");   dvConstraint = DVConstraint.createFormulaListConstraint("list1");        
这样也是可以的: 
  dvConstraint = DVConstraint.createFormulaListConstraint("'Data Sheet'!$A$1:$A$3"); 
但这样是不行的: 
  HSSFNamedRange namedRange = workbook.createName();   namedRange.setNameName("list1");   namedRange.setRefersToFormula("'Sheet1'!$A$1:$A$3");   dvConstraint = DVConstraint.createFormulaListConstraint("list1");        
这样也是不行的: 
  dvConstraint = DVConstraint.createFormulaListConstraint("'Sheet1'!$A$1:$A$3"); 
嵌入其他资源对象 
可以对嵌入的 Excel、word、PowerPoint 文档或者其他类型的嵌入对象进行更加进行的 操作。 
HSSF:  
  POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("excel_with_embeded.xls"));   HSSFWorkbook workbook = new HSSFWorkbook(fs);   for (HSSFObjectData obj : workbook.getAllEmbeddedObjects()) {       //该对象的 OLE2 类名 
POI3.5 HSSF&XSSF Excel 操作快速入门 
36 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
      String oleName = obj.getOLE2ClassName();       if (oleName.equals("Worksheet")) {           DirectoryNode dn = (DirectoryNode) obj.getDirectory();           HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(dn, fs, false);           //System.out.println(entry.getName() + ": " + embeddedWorkbook.getNumberOfSheets());       } else if (oleName.equals("Document")) {           DirectoryNode dn = (DirectoryNode) obj.getDirectory();           HWPFDocument embeddedWordDocument = new HWPFDocument(dn, fs);           //System.out.println(entry.getName() + ": " + embeddedWordDocument.getRange().text());       }  else if (oleName.equals("Presentation")) {           DirectoryNode dn = (DirectoryNode) obj.getDirectory();           SlideShow embeddedPowerPointDocument = new SlideShow(new HSLFSlideShow(dn, fs));           //System.out.println(entry.getName() + ": " + embeddedPowerPointDocument.getSlides().length);       } else {           if(obj.hasDirectoryEntry()){        // 文件夹实体类(DirectoryEntry)是一个文档节点( DocumentNode) // 检查它的实体,获得它的内容               DirectoryNode dn = (DirectoryNode) obj.getDirectory();               for (Iterator entries = dn.getEntries(); entries.hasNext();) {                   Entry entry = (Entry) entries.next();                   //System.out.println(oleName + "." + entry.getName());               }           } else {               // 如果没有文件夹实体类(DirectoryEntry)               //从 HSSFObjectData 对象中恢复嵌入文档的数据               byte[] objectData = obj.getObjectData();           }       }   }         
XSSF:  
  XSSFWorkbook workbook = new XSSFWorkbook("excel_with_embeded.xlsx");   for (PackagePart pPart : workbook.getAllEmbedds()) {       String contentType = pPart.getContentType(); 
POI3.5 HSSF&XSSF Excel 操作快速入门 
37 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
      //Excel 工作簿 二进制或 OpenXML 格式       if (contentType.equals("application/vnd.ms-excel")) {           HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(pPart.getInputStream());       }       //Excel 工作簿 OpenXML 格式       else if (contentType.equals("application/vnd.openxmlformats-officedocumen t.spreadsheetml.sheet")) {           OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());           XSSFWorkbook embeddedWorkbook = new XSSFWorkbook(docPackage);       }       // word 文档- 二进制 (OLE2CDF) 文件格式       else if (contentType.equals("application/msword")) {           HWPFDocument document = new HWPFDocument(pPart.getInputStream());       }       // word 文档 - OpenXML 文件格式       else if (contentType.equals("application/vnd.openxmlformats-officedocumen t.wordprocessingml.document")) {           OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());           XWPFDocument document = new XWPFDocument(docPackage);       }       //PPT 文档 –二进制文件格式       else if (contentType.equals("application/vnd.ms-powerpoint")) {           HSLFSlideShow slideShow = new HSLFSlideShow(pPart.getInputStream());       }       // PPT 文档 - OpenXML 文件格式       else if (contentType.equals("application/vnd.openxmlformats-officedocumen t.presentationml.presentation")) {           OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());           XSLFSlideShow slideShow = new XSLFSlideShow(docPackage);       }       //其他的嵌入文件格式.       else {           System.out.println("Unknown Embedded Document: " + 
POI3.5 HSSF&XSSF Excel 操作快速入门 
38 
本文翻译自 http://poi.apache.org/spreadsheet/quick-guide.html
欢迎交流指正                岑坚 ( 高凯 )hellonickco.javaeye.com 
contentType);           InputStream inputStream = pPart.getInputStream();       }   } 
 

 

你可能感兴趣的:(web,java,开发语言)