java控制Office套件API(POI加JXL)网上摘录留工作备查

在Java中,已经有很多对于Word、Excel的开源的解决方案,其中比较出色的是 Apache的Jakata项目的POI子项目。该项目的官方网站是http://jakarta.apache.org/poi/。POI包括一系列的API,它们可以操作基于 MicroSoft OLE 2 Compound Document Format的各种格式文件,可以通过这些API在Java中读写Excel、Word等文件。POI是完全的Java Excel和Java Word解决方案。POI子项目包括:POIFS、HSSF、HDF、HPSF。

子项目名

说明

POIFS(POI File System)

POIFS是POI项目中最早的最基础的一个模块,是Java到OLE 2 Compound Document Format的接口,支持读写功能,所有的其他项目都依赖与该项目。

HSSF(Horrible Spreadsheet Format)

HSSF是Java到Microsoft Excel 97(-2002)文件的接口,支持读写功能

HWPF(Horrible Word Processing Format)

HWPF是Java到Microsoft Word 97文件的接口,支持读写功能,但目前该模块还处于刚开始开发阶段,只能实现一些简单文件的操作,在后续版本中,会提供更强大的支持

HPSF(Horrible Property Set Format)

HPSF 是Java到OLE 2 Compound Document Format文件的属性设置的接口,属性设置通常用来设置文档的属性(标题,作者,最后修改日期等),还可以设置用户定义的属性。HPSF支持读写功能,当前发布版本中直支持读功能。

7.3.1  对Excel的处理类

下面通过HSSF提供的接口对Excel文件经 行处理。首先需要下载POI的包,可以到apache的官方网站下载,地址为:http://apache.justdn.org/jakarta /poi/,本书采用的是poi-2.5.1-final-20040804.jar,读者可以下载当前的稳定版本。把下载的包按照前面介绍的方式加入 Build Path,然后新建一个ch7.poi包,并创建一个ExcelReader类。

ExcelReader类可以读取一个XLS文件,然后将其内容逐行提取出来,写入文本文件。其代码如下。

代码7.6

public class ExcelReader {

   // 创建文件输入流

   private BufferedReader reader = null;

   // 文件类型

   private String filetype;

   // 文件二进制输入流

   private InputStream is = null;

   // 当前的Sheet

   private int currSheet;

   // 当前位置

   private int currPosition;

   // Sheet数量

   private int numOfSheets;

   // HSSFWorkbook

   HSSFWorkbook workbook = null;

   // 设置Cell之间以空格分割

   private static String EXCEL_LINE_DELIMITER = " ";

   // 设置最大列数

   private static int MAX_EXCEL_COLUMNS = 64;

   // 构造函数创建一个ExcelReader

   public ExcelReader(String inputfile) throws IOException, Exception {

      // 判断参数是否为空或没有意义

      if (inputfile == null || inputfile.trim().equals("")) {

         throw new IOException("no input file specified");

      }

      // 取得文件名的后缀名赋值给filetype

      this.filetype = inputfile.substring(inputfile.lastIndexOf(".") + 1);

      // 设置开始行为0

      currPosition = 0;

      // 设置当前位置为0

      currSheet = 0;

      // 创建文件输入流

      is = new FileInputStream(inputfile);

      // 判断文件格式

      if (filetype.equalsIgnoreCase("txt")) {

         // 如果是txt则直接创建BufferedReader读取

         reader = new BufferedReader(new InputStreamReader(is));

      }

else if (filetype.equalsIgnoreCase("xls")) {

         // 如果是Excel文件则创建HSSFWorkbook读取

         workbook = new HSSFWorkbook(is);

         // 设置Sheet数

         numOfSheets = workbook.getNumberOfSheets();

      }

else {

         throw new Exception("File Type Not Supported");

      }

   }

   // 函数readLine读取文件的一行

   public String readLine() throws IOException {

      // 如果是txt文件则通过reader读取

      if (filetype.equalsIgnoreCase("txt")) {

         String str = reader.readLine();

         // 空行则略去,直接读取下一行

         while (str.trim().equals("")) {

            str = reader.readLine();

         }

         return str;

      }

      // 如果是XLS文件则通过POI提供的API读取文件

      else if (filetype.equalsIgnoreCase("xls")) {

         // 根据currSheet值获得当前的sheet

         HSSFSheet sheet = workbook.getSheetAt(currSheet);

         // 判断当前行是否到但前Sheet的结尾

         if (currPosition > sheet.getLastRowNum()) {

            // 当前行位置清零

            currPosition = 0;

            // 判断是否还有Sheet

            while (currSheet != numOfSheets - 1) {

               // 得到下一张Sheet

               sheet = workbook.getSheetAt(currSheet + 1);

               // 当前行数是否已经到达文件末尾

               if (currPosition == sheet.getLastRowNum()) {

                  // 当前Sheet指向下一张Sheet

                  currSheet++;

                  continue;

               } else {

                  // 获取当前行数

                  int row = currPosition;

                  currPosition++;

                  // 读取当前行数据

                  return getLine(sheet, row);

               }

            }

            return null;

         }

         // 获取当前行数

         int row = currPosition;

         currPosition++;

         // 读取当前行数据

         return getLine(sheet, row);

      }

      return null;

   }

   // 函数getLine返回Sheet的一行数据

   private String getLine(HSSFSheet sheet, int row) {

      // 根据行数取得Sheet的一行

      HSSFRow rowline = sheet.getRow(row);

      // 创建字符创缓冲区

      StringBuffer buffer = new StringBuffer();

      // 获取当前行的列数

      int filledColumns = rowline.getLastCellNum();

      HSSFCell cell = null;

      // 循环遍历所有列

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

         // 取得当前Cell

         cell = rowline.getCell((short) i);

         String cellvalue = null;

         if (cell != null) {

            // 判断当前Cell的Type

            switch (cell.getCellType()) {

            // 如果当前Cell的Type为NUMERIC

            case HSSFCell.CELL_TYPE_NUMERIC: {

               // 判断当前的cell是否为Date

               if (HSSFDateUtil.isCellDateFormatted(cell)) {

                  // 如果是Date类型则,取得该Cell的Date值

                  Date date = cell.getDateCellValue();

                  // 把Date转换成本地格式的字符串

                  cellvalue = cell.getDateCellValue().toLocaleString();

               }

               // 如果是纯数字

               else {

                  // 取得当前Cell的数值

                  Integer num = new Integer((int) cell

                        .getNumericCellValue());

                  cellvalue = String.valueOf(num);

               }

               break;

            }

            // 如果当前Cell的Type为STRIN

            case HSSFCell.CELL_TYPE_STRING:

               // 取得当前的Cell字符串

               cellvalue = cell.getStringCellValue().replaceAll("'", "''");

               break;

            // 默认的Cell值

            default:

               cellvalue = " ";

            }

         } else {

            cellvalue = "";

         }

         // 在每个字段之间插入分割符

         buffer.append(cellvalue).append(EXCEL_LINE_DELIMITER);

      }

      // 以字符串返回该行的数据

      return buffer.toString();

   }

   // close函数执行流的关闭操作

   public void close() {

      // 如果is不为空,则关闭InputSteam文件输入流

      if (is != null) {

         try {

            is.close();

         } catch (IOException e) {

            is = null;

         }

      }

      // 如果reader不为空则关闭BufferedReader文件输入流

      if (reader != null) {

         try {

            reader.close();

         } catch (IOException e) {

            reader = null;

         }

      }

   }

}

7.3.2  ExcelReader的运行效果

下面创建一个main函数,用来测试上面的ExcelReader类,代码如下。

代码7.7

    public static void main(String[] args) {

        try{

            ExcelReader er=new ExcelReader("c:\xp.xls");  

            String line=er.readLine();

            while(line != null){

                System.out.println(line);

                line=er.readLine();

            }

            er.close();

        }catch(Exception e){

            e.printStackTrace();

        }

    }

main函数先创建一个ExcelReader类,然后调用它提供的接口readLine,对XLS文件进行读取,打印到控制台,处理前的XLS文件。

写文件

package IO.file;

imp
ort java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.Region;

public class ExcelFile {

public void writeExcel(String fileName) {
// 目标文件
File file = new File(fileName);
FileOutputStream fOut = null;

// 创建excel工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
// 在excel工作簿中创建一个工作表,其名是默认
// 也可以指定工作表的名字
HSSFSheet sheet = workbook.createSheet("Test_Table");

// 创建字体,红色、粗体
HSSFFont font = workbook.createFont();
font.setColor(HSSFFont.COLOR_RED);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

// 设置字体
HSSFFont font = workbook.createFont();
font.setFontHeightInPoints(( short ) 20 ); // 字体高度
font.setColor(HSSFFont.COLOR_RED); // 字体颜色
font.setFontName( " 黑体 " ); // 字体
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 宽度
font.setItalic( true ); // 是否使用斜体
font.setStrikeout(true); // 是否使用划线

// 设置单元格类型
HSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setFont(font);
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平布局:居中

cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); //垂直居中
cellStyle.setWrapText( true );

// 添加单元格注释
// 创建HSSFPatriarch对象,HSSFPatriarch是所有注释的容器.
HSSFPatriarch patr = sheet.createDrawingPatriarch();
// 定义注释的大小和位置,详见文档
HSSFComment comment = patr.createComment( new HSSFClientAnchor( 0 , 0 , 0 , 0 , ( short ) 4 , 2 , ( short ) 6 , 5 ));
// 设置注释内容
comment.setString( new HSSFRichTextString( " 可以在POI中添加注释! " ));
// 设置注释作者. 当鼠标移动到单元格上是可以在状态栏中看到该内容.
comment.setAuthor( " Xuys. " );

// 创建单元格
HSSFCell cell = row.createCell(( short ) 1 );
HSSFRichTextString hssfString = new HSSFRichTextString( " Hello World! " );
cell.setCellValue(hssfString); // 设置单元格内容
cell.setCellStyle(cellStyle); // 设置单元格样式
cell.setCellType(HSSFCell.CELL_TYPE_STRING); // 指定单元格格式:数值、公式或字符串
cell.setCellComment(comment); // 添加注释

// 格式化数据
row = sheet.createRow(( short ) 2 );
cell = row.createCell(( short ) 2 );
cell.setCellValue( 11111.25 );
cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat(format.getFormat( " 0.0 " ));
cell.setCellStyle(cellStyle);

row = sheet.createRow(( short ) 3 );
cell = row.createCell(( short ) 3 );
cell.setCellValue( 9736279.073 );
cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat(format.getFormat( " #,##0.0000 " ));
cell.setCellStyle(cellStyle);


sheet.autoSizeColumn(( short ) 0 ); // 调整第一列宽度
sheet.autoSizeColumn(( short ) 1 ); // 调整第二列宽度
sheet.autoSizeColumn(( short ) 2 ); // 调整第三列宽度
sheet.autoSizeColumn(( short ) 3 ); // 调整第四列宽度

// 创建单元格的格式,如居中、左对齐等
HSSFCellStyle cellStyle = workbook.createCellStyle();
// 水平方向居中对齐
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 垂直方向居中对齐
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
// 设置字体
cellStyle.setFont(font);

// 下面将建立一个4行3列的表,第一行是表头
int rowNum = 0; // 行标
int colNum = 0; // 列标
// 设置表头信息
HSSFRow row = sheet.createRow(rowNum);

HSSFCell cell = null; // 创建单元格
for(colNum = 0; colNum < 5; colNum++) {
// 在当前行的colNum列上创建单元格
cell = row.createCell((short)colNum);
// 定义单元格为字符类型,也可以指定为日期类型、数字类型等
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
// 定义编码方面,为了支持中文,这里使用utf-16
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellStyle(cellStyle);
cell.setCellValue("表头名" + colNum);
}

rowNum++;
for(; rowNum < 5; rowNum++) {
// 新建第rowNum行
row = sheet.createRow(rowNum);
for(colNum = 0; colNum < 5; colNum++) {
cell = row.createCell((short)colNum);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellStyle(cellStyle);
cell.setCellValue("值-" + rowNum + "-" + colNum);
}
}


// 合并单元格
// 先创建2行5列的单元格,然后将这些单元格合并成2个大的单元格
rowNum = 5;
for(; rowNum < 7; rowNum++) {
row = sheet.createRow((short)rowNum);
for(colNum = 0; colNum < 5; colNum++)
cell = row.createCell((short)colNum);
}

// 建立第一个大单元格,高度是2,宽度也是2
rowNum = 5;
colNum = 0;
Region region = new Region(rowNum, (short)colNum, (rowNum + 1), (short)(colNum + 1));
sheet.addMergedRegion(region);
// 获得第一个大单元格
cell = sheet.getRow(rowNum).createCell((short)colNum);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellStyle(cellStyle);
cell.setCellValue("第一个大单元格");

// 建立第二个大单元格,高度是2,宽度是3
colNum = 2;
region = new Region(rowNum, (short)colNum, (rowNum + 1), (short)(colNum + 2));
sheet.addMergedRegion(region);
// 获得第二个大单元格
cell = sheet.getRow(rowNum).createCell((short)colNum);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellStyle(cellStyle);
cell.setCellValue("第二个大单元格");

// 工作簿建立完成,下面将工作簿存入文件
// 建立一个文件输出流
try {
fOut = new FileOutputStream(file);
workbook.write(fOut);
fOut.flush();
System.out.println("Excel文件生成成功!文件名:" + file.getAbsolutePath());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fOut != null)
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


public void readExcel(String fileName) {
File file = new File(fileName);
FileInputStream in = null;

try {
// 创建Excel工作簿文件的引用
in = new FileInputStream(file);
HSSFWorkbook workbook = new HSSFWorkbook(in);

// 创建对工作表的引用
// 这里使用按名引用
HSSFSheet sheet = workbook.getSheet("Test_Table");
// 也可以使用getSheetAt(int index)按索引引用
// 在Excel文档中,第一张工作表的默认引用是0,其语句是
// HSSFSheet sheet = workbook.getSheetAt(0);

HSSFRow row = null;
HSSFCell cell = null;
int rowNum = 0;
int colNum = 0;
for(; rowNum < 5; rowNum++) {
row = sheet.getRow(rowNum);
for(colNum = 0; colNum < 5; colNum++) {
cell = row.getCell(colNum);
System.out.print(cell.getStringCellValue() + "	");
}
System.out.println();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
ExcelFile excel = new ExcelFile();
String fileName = "c:/temp.xls";
excel.writeExcel(fileName);
excel.readExcel(fileName);
}

}

jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可供使用,一个是POI,一个是 jExcelAPI。其中功能相对POI比较弱一点。但jExcelAPI对中文支持非常好,API是纯Java的, 并不依赖Windows系统,即使 运行在Linux下,它同样能够正确的处理Excel文件。 另外需要说明的是,这套API对图形和图表的支持很有限,而且仅仅识别PNG格式。

使用如下:

搭建环境

 将下载后的文件解包,得到jxl.jar,放入classpath,安装就完成了。

 基本操作

 一、创建文件

 拟生成一个名为“test.xls”的Excel文件,其中第一个工作表被命名为
 “第一页”,大致效果如下:

 基本操作

 一、创建文件

 拟生成一个名为“test.xls”的Excel文件,其中第一个工作表被命名为
 “第一页”,大致效果如下:

package test;

//生成Excel的类
import java.io.File;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

public class CreateExcel {
    
public static void main(String args[]) {
        
try {
            
// 打开文件
            WritableWorkbook book = Workbook.createWorkbook(new File("test.xls"));
            
// 生成名为“第一页”的工作表,参数0表示这是第一页
            WritableSheet sheet = book.createSheet("第一页"0);
            
// 在Label对象的构造子中指名单元格位置是第一列第一行(0,0)
            
// 以及单元格内容为test
            Label label = new Label(00"test");

            
// 将定义好的单元格添加到工作表中
            sheet.addCell(label);

            
/*
             * 生成一个保存数字的单元格 必须使用Number的完整包路径,否则有语法歧义 单元格位置是第二列,第一行,值为789.123
             
*/

            jxl.write.Number number 
= new jxl.write.Number(10555.12541);
            sheet.addCell(number);

            
// 写入数据并关闭文件
            book.write();
            book.close();

        }
 catch (Exception e) {
            System.out.println(e);
        }

    }

}

   编译执行后,会产生一个Excel文件。

 三、读取文件

 以刚才我们创建的Excel文件为例,做一个简单的读取操作,程序代码如下:

package test;

//读取Excel的类
import java.io.File;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;

public class ReadExcel {
    
public static void main(String args[]) {
        
try {
            Workbook book 
= Workbook.getWorkbook(new File("test.xls"));
            
// 获得第一个工作表对象
            Sheet sheet = book.getSheet(0);
            
// 得到第一列第一行的单元格
            Cell cell1 = sheet.getCell(00);
            String result 
= cell1.getContents();
            System.out.println(result);
            book.close();
        }
 catch (Exception e) {
            System.out.println(e);
        }

    }

}


  程序执行结果:test

 四、修改文件
 利用jExcelAPI可以修改已有的Excel文件,修改Excel文件的时候,除了打开文件的方式不同之外,
 其他操作和创建Excel是一样的。下面的例子是在我们已经生成的Excel文件中添加一个工作表:

package test;

import java.io.File;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

public class UpdateExcel {
    
public static void main(String args[]) {
        
try {
            
// Excel获得文件
            Workbook wb = Workbook.getWorkbook(new File("test.xls"));
            
// 打开一个文件的副本,并且指定数据写回到原文件
            WritableWorkbook book = Workbook.createWorkbook(new File("test.xls"),
                    wb);
            
// 添加一个工作表
            WritableSheet sheet = book.createSheet("第二页"1);
            sheet.addCell(
new Label(00"第二页的测试数据"));
            book.write();
            book.close();
        }
 catch (Exception e) {
            System.out.println(e);
        }

    }

}


其他操作

 一、 数据格式化

 在Excel中不涉及复杂的数据类型,能够比较好的处理字串、数字和日期已经能够满足一般的应用。

 1、 字串格式化

 字符串的格式化涉及到的是字体、粗细、字号等元素,这些功能主要由WritableFont和
 WritableCellFormat类来负责。假设我们在生成一个含有字串的单元格时,使用如下语句,
 为方便叙述,我们为每一行命令加了编号:

WritableFont font1=
 
new WritableFont(WritableFont.TIMES,16,WritableFont.BOLD); ①

 WritableCellFormat format1
=new WritableCellFormat(font1); ②

 Label label
=new Label(0,0,”data 4 test”,format1) ③

  其中①指定了字串格式:字体为TIMES,字号16,加粗显示。WritableFont有非常丰富的
 构造子,供不同情况下使用,jExcelAPI的java-doc中有详细列表,这里不再列出。

 ②处代码使用了WritableCellFormat类,这个类非常重要,通过它可以指定单元格的各种
 属性,后面的单元格格式化中会有更多描述。

 ③处使用了Label类的构造子,指定了字串被赋予那种格式。

 在WritableCellFormat类中,还有一个很重要的方法是指定数据的对齐方式,比如针对我们
 上面的实例,可以指定:

 //把水平对齐方式指定为居中
 format1.setAlignment(jxl.format.Alignment.CENTRE);

 
//把垂直对齐方式指定为居中
 format1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);

二、单元格操作

 Excel中很重要的一部分是对单元格的操作,比如行高、列宽、单元格合并等,所幸jExcelAPI
 提供了这些支持。这些操作相对比较简单,下面只介绍一下相关的API。

 1、 合并单元格

 WritableSheet.mergeCells(int m,int n,int p,int q); 

 
//作用是从(m,n)到(p,q)的单元格全部合并,比如:
 WritableSheet sheet=book.createSheet(“第一页”,0);

 
//合并第一列第一行到第六列第一行的所有单元格
 sheet.mergeCells(0,0,5,0);

 合并既可以是横向的,也可以是纵向的。合并后的单元格不能再次进行合并,否则会触发异常。

 2、 行高和列宽

 WritableSheet.setRowView(int i,int height);

 
//作用是指定第i+1行的高度,比如:

 
//将第一行的高度设为200
 sheet.setRowView(0,200);

 WritableSheet.setColumnView(
int i,int width);

 
//作用是指定第i+1列的宽度,比如:

 
//将第一列的宽度设为30
 sheet.setColumnView(0,30);

 jExcelAPI还有其他的一些功能,比如插入图片等,这里就不再一一介绍,读者可以自己探索。

其中:如果读一个excel,需要知道它有多少行和多少列,如下操作:

Workbook book = Workbook.getWorkbook(new File("测试1.xls"));
        
// 获得第一个工作表对象
        Sheet sheet = book.getSheet(0);
        
// 得到第一列第一行的单元格
        int columnum = sheet.getColumns();// 得到列数
        int rownum = sheet.getRows();// 得到行数
        System.out.println(columnum);
        System.out.println(rownum);
        
for (int i = 0; i < rownum; i++)// 循环进行读写
        {
            
for (int j = 0; j < columnum; j++{
                Cell cell1 
= sheet.getCell(j, i);
                String result 
= cell1.getContents();
                System.out.print(result);
                System.out.print(
" ");
            }

            System.out.println();
        }

        book.close();
原文地址:https://www.cnblogs.com/pg-young/p/3777751.html