Java操作Microsoft Office(Excel) Apache POI
来源:互联网 发布:华彩软件站 编辑:程序博客网 时间:2024/06/05 07:45
Java操作Microsoft Office用到的专业的类库为Apache POI。Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。此篇文章只介绍对Excel(.xls/.xlsx)的操作,包括:创建、查询、修改、删除、更新等。
1 Excel的创建
Excel的创建可以分为2007版本及其以上(.xlsx)和2007版本一下的(.xls),其完整的Excel创建代码如下:
import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.List;import javax.swing.JOptionPane;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import org.apache.poi.ss.usermodel.Row;/** * 创建Excel的操作 * @author liguohui * */public class ExcelCreater {private String filePath = null; // Excel文件的路径(包含文件名)private List<String> definition = null;/** * 构造方法 * @param filePath 要创建的Excel文件的路径(包含文件名) * @param definition 该表格的定义。(即表格第一行的内容) */public ExcelCreater(String filePath, List<String> definition) {this.filePath = filePath;this.definition = definition;}/** * 创建 * @return */public Workbook create() {File file = new File(filePath);if(file.exists()) { //文件已经存在int op = JOptionPane.showConfirmDialog(null, "文件:" + filePath + " 已经存在,是否覆盖?", "提示信息", 0);if(op == 0) { //选择了:是file.delete(); //必须先删除,要不然下面就是对Excel表格进行append,而不是覆盖添加} else { //选择了:否或直接点Xreturn null;}}Workbook workbook = null;if(filePath.endsWith(".xlsx") || filePath.endsWith(".XLSX")) { //2007版本及以上workbook = new XSSFWorkbook();} else if(filePath.endsWith(".xls") || filePath.endsWith(".XLS")){ //97-03版本workbook = new HSSFWorkbook();} else {throw new RuntimeException("文件格式错误");}Sheet sheet = workbook.createSheet(); //创建一个Sheetif(definition != null && definition.size() > 0) {//添加表格的定义,即:写第一行Row row = sheet.createRow(0);Cell cell;for(int i=0; i<definition.size(); i++) {cell = row.createCell(i);cell.setCellValue(definition.get(i));}}writeToFile(workbook);return workbook;}/** * 写入到硬盘 */private synchronized void writeToFile(Workbook workbook) {FileOutputStream fOut = null;try {File f = new File(filePath);if(!f.getParentFile().exists()) {f.getParentFile().mkdirs();}fOut = new FileOutputStream(filePath);workbook.write(fOut); // 把相应的Excel 工作簿存盘fOut.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {fOut.close(); // 操作结束,关闭文件} catch (IOException e) {e.printStackTrace();}}}}
测试代码如下:
public void testCreateExcel() {List<String> defination = new ArrayList<String>();defination.add("id号");defination.add("名称");ExcelCreater ec = new ExcelCreater("F:\\dd.xlsx", defination);ec.create();}
运行结果如下:
2 Excel的操作(查询、修改、删除、更新)
2.1 插入
/** * 插入一行到指定的位置,该行下面的所有行向下移动一个 * @param rowIndex 带插入的行(Excel表中,行是从0起算的,但该值不能为0,因为:不能插入在第0行,因为第0行为用来定义字段的!) * @param objs 待插入的值 */public synchronized void insert(int rowIndex, String[] objs) {if(rowIndex == 0) {throw new IllegalArgumentException("不能插入在第0行,因为第0行为用来定义字段的!");}if(rowIndex > sheet.getLastRowNum() + 1) {throw new IllegalArgumentException("最多只能插入在最后一行的后面,不能再往后插入了");}int referRowIndex = -1; //参考行的行号。if(sheet.getPhysicalNumberOfRows() <= 1) { //原始的表格里面没有值referRowIndex = rowIndex - 1;} else {referRowIndex = rowIndex - 1;if(rowIndex == sheet.getLastRowNum() + 1) { //是插入最后一行//什么都不做} else {sheet.shiftRows(rowIndex, sheet.getLastRowNum(), 1, true, false); //下移动一位}}Row targetRow = sheet.createRow(rowIndex);Row referRow = sheet.getRow(referRowIndex); // 参考行Cell targetCell, referCell;for (int i = 0; i < objs.length; i++) {targetCell = targetRow.createCell(i);referCell = referRow.getCell(i);targetCell.setCellStyle(referCell.getCellStyle());targetCell.setCellType(referCell.getCellType());targetCell.setCellValue(objs[i]);// 设置值}writeToFile();}
2.2 更新
public synchronized void update(int rowIndex, String[] objs) {Row row = sheet.getRow(rowIndex);for(int i=0; i<objs.length; i++) {row.getCell(i).setCellValue(objs[i]);}writeToFile();}
2.3 删除
/** * 删除一行数据(Excel表中,行是从0起算的) * @param rowIndex 要删除的行 */public synchronized void delete(int rowIndex) {if(rowIndex == sheet.getLastRowNum()) { //删除的是最后一行sheet.removeRow(sheet.getRow(sheet.getLastRowNum()));} else { //删除的不是最后一行sheet.shiftRows(rowIndex + 1, sheet.getLastRowNum(), -1, true, false);sheet.removeRow(sheet.getRow(sheet.getLastRowNum() + 1));}writeToFile();}
2.4 读取
/** * 读取Excel中的【所有】二维表数据 * * @throws IOException */public synchronized String[][] read() throws IOException {String[][] objs = new String[sheet.getPhysicalNumberOfRows()][];Row row = sheet.getRow(sheet.getFirstRowNum());int firstCellNum = row.getFirstCellNum();int lastCellNum = row.getLastCellNum();int r = 0, c = 0;Cell cell = null;for(int i=sheet.getFirstRowNum(); i<=sheet.getLastRowNum(); i++) {row = sheet.getRow(i);if(row == null) continue;objs[r] = new String[lastCellNum - firstCellNum];for(int j=firstCellNum; j<lastCellNum; j++) {cell = row.getCell(j);objs[r][c] = (cell == null ? null : cell.toString());c++;}r++;c = 0;}return objs;}
其完整的Excel代码如下:
import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.LinkedHashMap;import org.apache.poi.openxml4j.exceptions.InvalidFormatException;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.ss.usermodel.WorkbookFactory;import org.apache.poi.xssf.usermodel.XSSFCell;import cn.edu.njnu.pm.dao.Blackboard;import cn.edu.njnu.pm.dao.PMP;/** * Excel的CRUD操作,但没有Excel文件的创建的操作,其创建操作专门放在ExcelCreater类里 * * @author liguohui * @version 2013/03/14 */public class ExcelEditor { private String filePath = null; // Excel文件的路径(包含文件名)// private int sheetIndex = -1; // 要读取的sheet的序号 Workbook workbook = null; Sheet sheet = null; /** * 构造函数。操作了该构造函数后,表格里面的所有项都会设置为String类型 * * @param filePath * Excel文件的路径(包含文件名) * @param sheetIndex * 要读取的sheet的序号 */ public ExcelEditor(String filePath, int sheetIndex) { this.filePath = filePath;// this.sheetIndex = sheetIndex; try { InputStream inp = new FileInputStream(filePath); workbook = WorkbookFactory.create(inp); sheet = workbook.getSheetAt(sheetIndex); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //将所有的都设为String类型,不管事数字形式的还是日期形式的 Row row = sheet.getRow(sheet.getFirstRowNum()); Cell cell = null; for(int i=sheet.getFirstRowNum(); i<=sheet.getLastRowNum(); i++) { row = sheet.getRow(i); if(row == null) continue; for(int j=row.getFirstCellNum(); j<row.getLastCellNum(); j++) { cell = row.getCell(j); if(cell != null) cell.setCellType(XSSFCell.CELL_TYPE_STRING); } } writeToFile(); } /** * 获取每一列的宽度 * * @return 每一列的宽度 */ public int[] getColumnWidths() { int[] widths = new int[sheet.getRow(0).getPhysicalNumberOfCells()]; for (int i = 0; i < widths.length; i++) { widths[i] = sheet.getColumnWidth(i); } return widths; } /** * 在表格中添加一行数据到表格的最后 * @param objs */ public synchronized void add(String[] objs) { insert(sheet.getLastRowNum() + 1, objs); } /** * 插入一行到指定的位置,该行下面的所有行向下移动一个 * @param rowIndex 带插入的行(Excel表中,行是从0起算的,但该值不能为0,因为:不能插入在第0行,因为第0行为用来定义字段的!) * @param objs 待插入的值 */ public synchronized void insert(int rowIndex, String[] objs) { if(rowIndex == 0) { throw new IllegalArgumentException("不能插入在第0行,因为第0行为用来定义字段的!"); } if(rowIndex > sheet.getLastRowNum() + 1) { throw new IllegalArgumentException("最多只能插入在最后一行的后面,不能再往后插入了"); } int referRowIndex = -1; //参考行的行号。 if(sheet.getPhysicalNumberOfRows() <= 1) { //原始的表格里面没有值 referRowIndex = rowIndex - 1; } else { referRowIndex = rowIndex - 1; if(rowIndex == sheet.getLastRowNum() + 1) { //是插入最后一行 //什么都不做 } else { sheet.shiftRows(rowIndex, sheet.getLastRowNum(), 1, true, false); //下移动一位 } } Row targetRow = sheet.createRow(rowIndex); Row referRow = sheet.getRow(referRowIndex); // 参考行 Cell targetCell, referCell; for (int i = 0; i < objs.length; i++) { targetCell = targetRow.createCell(i); referCell = referRow.getCell(i); targetCell.setCellStyle(referCell.getCellStyle()); targetCell.setCellType(referCell.getCellType()); targetCell.setCellValue(objs[i]);// 设置值 } writeToFile(); } /** * 更新指定的一行 * @param rowIndex 待更行的行(Excel表中,行是从0起算的) * @param objs 更新的数据 */ public synchronized void update(int rowIndex, String[] objs) { Row row = sheet.getRow(rowIndex); for(int i=0; i<objs.length; i++) { row.getCell(i).setCellValue(objs[i]); } writeToFile(); } /** * 删除一行数据(Excel表中,行是从0起算的) * @param rowIndex 要删除的行 */ public synchronized void delete(int rowIndex) { if(rowIndex == sheet.getLastRowNum()) { //删除的是最后一行 sheet.removeRow(sheet.getRow(sheet.getLastRowNum())); } else { //删除的不是最后一行 sheet.shiftRows(rowIndex + 1, sheet.getLastRowNum(), -1, true, false); sheet.removeRow(sheet.getRow(sheet.getLastRowNum() + 1)); } writeToFile(); } /** * 更新列表宽度,自动调整的适合的宽度 */ public synchronized void autoSizeColumns() { Row firstRow = sheet.getRow(sheet.getFirstRowNum()); for(int i=firstRow.getFirstCellNum(); i<firstRow.getLastCellNum(); i++) { sheet.autoSizeColumn(i); } writeToFile(); } /** * 读取Excel中的【所有】二维表数据 * * @throws IOException */ public synchronized String[][] read() throws IOException { String[][] objs = new String[sheet.getPhysicalNumberOfRows()][]; Row row = sheet.getRow(sheet.getFirstRowNum()); int firstCellNum = row.getFirstCellNum(); int lastCellNum = row.getLastCellNum(); int r = 0, c = 0; Cell cell = null; for(int i=sheet.getFirstRowNum(); i<=sheet.getLastRowNum(); i++) { row = sheet.getRow(i); if(row == null) continue; objs[r] = new String[lastCellNum - firstCellNum]; for(int j=firstCellNum; j<lastCellNum; j++) { cell = row.getCell(j); objs[r][c] = (cell == null ? null : cell.toString()); c++; } r++; c = 0; } return objs; } /** * 更新完成后,写入到硬盘 */ private synchronized void writeToFile() { FileOutputStream fOut = null; try { fOut = new FileOutputStream(filePath); workbook.write(fOut); // 把相应的Excel 工作簿存盘 fOut.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fOut.close(); // 操作结束,关闭文件 } catch (IOException e) { e.printStackTrace(); } } } /** * 根据传入的值找到其所在的列 * @param name * @return 列的序号,从0起算 */ public int columnIndex(String name) { Row row; Cell cell; for(int i=sheet.getFirstRowNum(); i<=sheet.getLastRowNum(); i++) { row = sheet.getRow(i); for(int j=row.getFirstCellNum(); j<row.getLastCellNum(); j++) { cell = row.getCell(j); if(cell.getStringCellValue().equals(name)) { return j; } } } return -1; }}
0 0
- Java操作Microsoft Office(Excel) Apache POI
- Apache POI 操作Office文档(Excel,Word)
- POI:全面了解POI操作Microsoft Office(Word、Excel、PowerPoint)
- Apache POI API操作Microsoft Office格式文件的方法+JAVA调用exe可执行文件
- Apache POI for Microsoft Office
- POI操作Microsoft Office(Word、Excel、PowerPoint)全面了解
- Apache POI 处理 Microsoft Office文档
- java使用Apache POI操作excel文件
- java使用Apache POI操作excel文件
- Java Apache POI组件操作Excel
- Apache POI 操作Excel
- [Apache POI] 操作Excel
- Apache POI 操作Excel
- Apache POI 操作Excel
- Apache POI操作Excel
- Apache POI操作excel
- Java读写Excel之POI超入门 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式
- 一脸懵逼学习Java操作Excel之POI(Apache POI)
- linux命令之cp:略过目录
- c++的一些小程序!
- spydroid源码分析(一):介绍spydroid每个包的大体功能
- sql行列互转,不是很专业,但也能满足需求。
- hdu_1003_Max Sum hdu_1058_Humble Numbers hdu_1059_Dividing
- Java操作Microsoft Office(Excel) Apache POI
- Java 模式3(结构模式) - 享元模式,门面模式,桥梁模式
- 适配多屏幕的最佳实践
- iOS定制修改navigation的back按钮
- K-means聚类
- codevs - 字符串 - 青铜合集
- Eclipse出现appcompat_v7错误的解决办法
- linux的一些细节!
- HDU 1226 超级密码