poi操做excel的基本用法

這周公司要用excel做爲數據存儲格式作一個文具申請的功能,感受之前原本很簡單的功能變複雜了很多,可是仍是記錄一下一些excel的基本用法。html

寫在最前面:這裏只介紹一些excel的基本存儲方式(讀,寫,數據和樣式),高級用法並不會涉及。java

首先是須要引入的jar包,以下表所示:(如下內容來自於Apache POI的官方文檔)apache

Apache POI能夠運用在許多文檔文件的格式中。這些對文檔操做的支持須要一些jar文件。不是全部的jar文件都被須要於每個格式中。下面的表格列出了在POI部件中的關係,maven倉庫的tags,和項目須要的jar文件。api

 

組件 應用類型 Maven artifactId 注意
POIFS OLE2 Filesystem poi Required to work with OLE2 / POIFS based files
HPSF OLE2 Property Sets poi  
HSSF Excel XLS poi For HSSF only, if common SS is needed see below
HSLF PowerPoint PPT poi-scratchpad  
HWPF Word DOC poi-scratchpad  
HDGF Visio VSD poi-scratchpad  
HPBF Publisher PUB poi-scratchpad  
HSMF Outlook MSG poi-scratchpad  
DDF Escher common drawings poi  
HWMF WMF drawings poi-scratchpad  
OpenXML4J OOXML poi-ooxml plus either poi-ooxml-schemasor
ooxml-schemas and ooxml-security
See notes below for differences between these options
XSSF Excel XLSX poi-ooxml  
XSLF PowerPoint PPTX poi-ooxml  
XWPF Word DOCX poi-ooxml  
Common SL PowerPoint PPT and PPTX poi-scratchpad and poi-ooxml SL code is in the core POI jar, but implementations are in poi-scratchpad and poi-ooxml.
Common SS Excel XLS and XLSX poi-ooxml WorkbookFactory and friends all require poi-ooxml, not just core poi

下面是maven倉庫所須要的jar包:數組

 

Maven artifactId 預先準備 JAR
poi commons-loggingcommons-codeclog4j poi-version-yyyymmdd.jar
poi-scratchpad poi poi-scratchpad-version-yyyymmdd.jar
poi-ooxml poipoi-ooxml-schemas poi-ooxml-version-yyyymmdd.jar
poi-ooxml-schemas xmlbeans poi-ooxml-schemas-version-yyyymmdd.jar
poi-examples poipoi-scratchpadpoi-ooxml poi-examples-version-yyyymmdd.jar
ooxml-schemas xmlbeans ooxml-schemas-1.3.jar
ooxml-security xmlbeans 
For signing: bcpkix-jdk15onbcprov-jdk15onxmlsecslf4j-api
ooxml-security-1.1.jar

綜上可知:咱們操做excel所須要poi,poi-ooxml和poi-ooxml-shemas這三類,請自行配置app

tips:excel分爲xls和xlsx,第一類是基於binary的標準,第二種是基於xml的規範,因此用不一樣的類進行操做maven

  • 新建一個excel文件:
/**
     * 新建一個excel 2003的文件,在項目的根目錄下
     */
    public void createHSSFWorkBooksTest() {
        try {
            Workbook wb = new HSSFWorkbook(); //這裏新建了一個exccel 2003的文件,因此
            //Workbook wb = new XSSFWorkbook();  這裏是一個excel2007的文件,相應的輸出流後綴應該是xlsx
            FileOutputStream fos = new FileOutputStream("workbook.xls");
            wb.write(fos);
            fos.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
  • 新建一個excel而且裏面有2個sheet,一個叫作sheet1,一個叫作sheet2
    /**
         * 新建一個excel 2003的文件,在項目的根目錄下
         */
        public void createHSSFWorkBooksTest() {
            try {
                Workbook wb = new HSSFWorkbook(); //這裏新建了一個exccel 2003的文件,因此
                //Workbook wb = new XSSFWorkbook();  這裏是一個excel2007的文件,相應的輸出流後綴應該是xlsx
                FileOutputStream fos = new FileOutputStream("workbook.xls");
                wb.write(fos);
                fos.close();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

     

  • 在單元格里面賦值,值爲1 ide

tips:在單元格里面能夠添加全部基本類型,以及公式,可是公式操做這裏不作介紹函數

    /**
     * 在第二行的第一個單元格里面賦值,值爲1
     * @throws Exception
     */
    public void testCreateCell() throws Exception {
        Workbook wb = new HSSFWorkbook();
        CreationHelper helper = wb.getCreationHelper();
        Sheet sheet = wb.createSheet("new Sheet");
        Row row = sheet.createRow(1);
        Cell cell = row.createCell(0);
        cell.setCellValue(1);
        FileOutputStream fos = new FileOutputStream("workbook.xls");
        wb.write(fos);
        fos.close();
    }
  • 在單元格里面添加日期類型
    /**
     * 在單元格里面添加日期類型的值
     * @throws Exception
     */
    public void testCreateDateCell() throws Exception {
        //新建一個excel2003的workbook
        Workbook wb = new HSSFWorkbook();
        //新建一個單元格
        Sheet sheet = wb.createSheet();
        CreationHelper helper = wb.getCreationHelper();
        //新建一行,且是第一行,java中的行是從0開始計算的
        Row row = sheet.createRow(0);
        //在第一行新建一個單元格
        Cell cell = row.createCell(0);
        //在這裏賦一個沒有轉換格式的日期類型
        cell.setCellValue(new Date());
        //經過workbook得到一個cellstyle
        CellStyle style = wb.createCellStyle();
        //進行日期類型的格式轉換
        style.setDataFormat(helper.createDataFormat().getFormat("m/d/yy h:mm"));
        //新建一個單元格,單元格的位置是第一行第二列
        cell = row.createCell(1);
        //賦值,變量爲日期類型
        cell.setCellValue(new Date());
        //該單元格的style爲上面的那種
        cell.setCellStyle(style);
        cell = row.createCell(2);
        //第二種得到日期的方法,經過調用java的canlendar
        cell.setCellValue(Calendar.getInstance());
        cell.setCellStyle(style);
        FileOutputStream fos = new FileOutputStream("workbook.xls");
        wb.write(fos);
        fos.close();
    }

 

  • 設置單元格里面的字體顏色
    /**
     * 設置不一樣的顏色顯示
     * @throws Exception
     */
    public void testCreateDifferentCell() throws Exception {
        Workbook wb = new HSSFWorkbook();
        Sheet sheet = wb.createSheet("new sheet");
        Row row = sheet.createRow(2);
        CellStyle style = wb.createCellStyle();
        //獲取一個font
        Font font = wb.createFont();
        //設置font的顏色爲紅色
        font.setColor(Font.COLOR_RED);
        style.setFont(font);
        row.createCell(0).setCellValue(1.2);
        row.getCell(0).setCellStyle(style);
        row.createCell(1).setCellValue(1);
        row.createCell(2).setCellValue(true);
        FileOutputStream fos = new FileOutputStream("workbook.xls");
        wb.write(fos);
        fos.close();
    }

 

  • 讀取已經有的excel有兩種方式:File和InputStream,可是在poi3.5以前不能用file的方式去讀
/**
     * 讀取已經存在excel的兩種方式
     * File && InputStream
     * 
     * @throws Exception
     */
    public void testCreateExcelByInputStreamAndFile() throws Exception {
        // Workbook wb = new HSSFWorkbook();
        Workbook wb = WorkbookFactory.create(new File("workbook.xls"));
        //Workbook wb = WorkbookFactory.create(new FileInputStream("workbook.xls"));
        Sheet sheet = wb.createSheet("new sheet");
        Row row = sheet.createRow(2);
        CellStyle style = wb.createCellStyle();
        // style.setFont(wb.createFont().setColor(Font.COLOR_RED));
        Font font = wb.createFont();
        font.setColor(Font.COLOR_RED);
        style.setFont(font);
        row.createCell(0).setCellValue(1.2);
        row.getCell(0).setCellStyle(style);
        row.createCell(1).setCellValue(1);
        row.createCell(2).setCellValue(true);
        wb.close();
        // FileOutputStream fos = new FileOutputStream("workbook.xls");
        // wb.write(fos);
        // fos.close();
    }

 

  • 循環excel裏面全部的元素,默認的迭代方式,不用迭代器,可是在poi3.5以前都不支持這樣的讀取方式
    /**
     * 循環excel裏面全部的元素,默認的迭代方式,不用迭代器,可是在poi3.5以前都不支持這樣的讀取方式
     * @throws Exception
     */
    public void testIterateAllExcel() throws Exception {
        Workbook wb = WorkbookFactory.create(new File("iterate.xls"));
        for (Sheet sheet : wb) {
            for (Row row : sheet) {
                for (Cell cell : row) {
                    if (cell == null) {
                        System.out.println("the cell is null!");
                    } else {
                        System.out.println(cell.getStringCellValue());

                    }
                }
            }
        }
        wb.close();
    }
  • 經過獲取cell內容的類型來調用相應的方法獲取cell裏面的值
    /**
     * 在excel的單元格內容有各式各樣的形式,因此讀取以前要先判斷讀取內容的類型,而後才能用相應的方式讀取出來
     * @throws Exception
     */
    public void testGetExcelContent() throws Exception {
        Workbook wb = WorkbookFactory.create(new File("iterate.xls"));
        Sheet sheet = wb.getSheetAt(0);
        for (Row row : sheet) {
            for (int i = 0; i < row.getLastCellNum(); i++) {
                //單元格的內容若是是空則返回null
                Cell cell = row.getCell(i, Row.RETURN_BLANK_AS_NULL);
                if (cell == null) {
                    System.out.println("the cell is null!");
                    continue;
                }
                //經過getCellType方法判斷單元格里面的內容
                switch (cell.getCellType()) {
                //獲取的內容爲string類型
                case Cell.CELL_TYPE_STRING:
                    System.out.println("the type is String:"
                            + cell.getRichStringCellValue().getString());
                    break;
                //獲取的內容爲數字類型(包括整型,浮點...)
                case Cell.CELL_TYPE_NUMERIC:
                    System.out.println("the type is numeric:"
                            + cell.getNumericCellValue());
                    break;
                //獲取的內容爲布爾類型
                case Cell.CELL_TYPE_BOOLEAN:
                    System.out.println("the type is boolean:"
                            + cell.getBooleanCellValue());
                    break;
                //獲取的內容爲公式類型
                case Cell.CELL_TYPE_FORMULA:
                    System.out.println("the type is formula:"
                            + cell.getCellFormula());
                    break;
                //獲取的內容爲black
                case Cell.CELL_TYPE_BLANK:
                    System.out.println("the type is null:" + cell);
                    break;
                default:
                    System.out.println("-");
                    break;
                }
            }
        }
        wb.close();
    }
  • 讀和從新寫入
    /**
     * 讀和從新寫入,就是輸入流和輸出流都對同一個文件作操做
     * @throws Exception
     */
    public void testExcelFont() throws Exception {
        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 testing merge");
        Font font = wb.createFont();
        font.setColor(IndexedColors.BLUE.getIndex());
        CellStyle style = wb.createCellStyle();
        style.setFont(font);
        cell.setCellStyle(style);
        FileOutputStream fos = new FileOutputStream("workbook.xls");
        wb.write(fos);
        wb.close();
        fos.close();
    }

 ------------------------------不知疲倦的翻越每個山丘,越過山丘,雖然已白了頭,更新於2016/09/29-------------------------------------------字體

 這裏本身寫了一個類,在構造函數時傳入excel的地址,就能夠經過裏面的方法讀取指定行,指定列,以及一個sheet中的所有內容,或者讀取整個excel,而且在javabean的屬性和excel對應列高度匹配時,能夠調用方法直接轉換成bean。

附代碼:

package com.rms.apply.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
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 com.rms.entity.Server;

public class POIExcelUtilHelper {
    private String excelPath;

    private Workbook wb = null;

    private InputStream inp = null;

    /**
     * the constructor method
     * 
     * @param excelPath
     *            the excel path like D://xxx.xlsx
     */
    public POIExcelUtilHelper(String excelPath) {
        this.excelPath = excelPath;
        try {
            inp = new FileInputStream(excelPath);
            wb = WorkbookFactory.create(inp);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * read one line in excel
     * 
     * @author mingzheng
     * @param sheet
     *            the sheet
     * @param rowNum
     *            the row line which you should read
     * @param startCellNum
     *            the start column which you begin to read
     * @param endCellNum
     *            the end of the column which you end to read(if the value is -1
     *            means read the line to the end of column)
     * @param notReadNum
     *            the columns which you don't want to read
     * @return an array of object
     */
    private Object[] readOneline(Sheet sheet, int rowNum, int startCellNum,    int endCellNum, int... notReadNum) {
        List<Integer> notReadList = new ArrayList<Integer>();
        for (int i = 0; i < notReadNum.length; i++) {
            notReadList.add(notReadNum[i]);
        }
        Row row = sheet.getRow(rowNum);
        if (row == null) {
            return null;
        }
        if (endCellNum == -1) {
            endCellNum = row.getLastCellNum();
        } else {
            endCellNum++;
        }
        int objectNum = endCellNum - startCellNum - notReadNum.length;
        Object[] object = new Object[objectNum];
        int j = 0;
        for (int i = startCellNum; i < endCellNum; i++) {
            if (notReadList.contains(i)) {
                System.out.println("the continue is:" + i);
                continue;
            }
            Cell cell = row.getCell(i);
            if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy",
                            Locale.ENGLISH);
                    object[j] = sdf.format(HSSFDateUtil.getJavaDate(cell
                            .getNumericCellValue()));
                } else {
                    object[j] = cell.getNumericCellValue();
                }
            } else if (cell.getCellType() == cell.CELL_TYPE_STRING) {
                object[j] = cell.getStringCellValue();
            } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
                try {
                    object[j] = cell.getNumericCellValue();
                } catch (IllegalStateException e) {
                    try {
                        object[j] = cell.getStringCellValue();
                    } catch (IllegalStateException e1) {
                        object[j] = "wrong!";
                    }
                }
            } else {
                object[j] = "";
            }
            j++;
        }
        return object;
    }

    /**
     * enter the sheet num and read the row and column which you want to read.
     * 
     * @author mingzheng
     * @param sheetNum
     *            the sheet num (begin with 0)
     * @param rowNum
     *            the row line which you should read
     * @param startCellNum
     *            the start column which you begin to read
     * @param endCellNum
     *            the end of the column which you end to read(if the value is -1
     *            means read the line to the end of column)
     * @param notReadNum
     *            the columns which you don't want to read
     * @return an array of object
     */
    public Object[] readOneObject(int sheetNum, int rowNum, int startCellNum,
            int endCellNum, int... notReadNum) {
        Sheet sheet = wb.getSheetAt(sheetNum);
        Object[] objects = readOneline(sheet, rowNum, startCellNum, endCellNum,
                notReadNum);
        return objects;
    }

    /**
     * enter the sheet name and read the row and column which you want to read.
     * 
     * @author mingzheng
     * @param sheetNum
     *            the sheet name
     * @param rowNum
     *            the row line which you should read
     * @param startCellNum
     *            the start column which you begin to read
     * @param endCellNum
     *            the end of the column which you end to read(if the value is -1
     *            means read the line to the end of column)
     * @param notReadNum
     *            the columns which you don't want to read
     * @return an array of object
     */
    public Object[] readOneObject(String sheetName, int rowNum,
            int startCellNum, int endCellNum, int... notReadNum) {
        Sheet sheet = wb.getSheet(sheetName);
        Object[] objects = readOneline(sheet, rowNum, startCellNum, endCellNum,
                notReadNum);
        return objects;
    }

    /**
     * 讀取excel裏面指定行和指定列,而且返回一個list包裝的object數組
     * 
     * @param sheetName
     *            sheet的名字
     * @param startRowNum
     *            開始的行號
     * @param endRowNum
     *            結束的行號
     * @param startCellNum
     *            開始的列號
     * @param endCellNum
     *            結束的列號
     * @param notReadNum
     *            在開始和結束列之間不用讀的列號
     * @return list包裝的object數組
     */
    public List<Object[]> readListObject(String sheetName, int startRowNum,
            int endRowNum, int startCellNum, int endCellNum, int... notReadNum) {
        List<Object[]> oList = new ArrayList<Object[]>();
        Sheet sheet = wb.getSheet(sheetName);
        if (endRowNum == -1) {
            endRowNum = sheet.getLastRowNum() + 1;
        } else {
            endRowNum++;
        }
        for (int i = startRowNum; i < endRowNum + 1; i++) {
            Object[] objects = readOneline(sheet, i, startCellNum, endCellNum,
                    notReadNum);
            oList.add(objects);
        }
        return oList;
    }

    /**
     * 讀一個excel的指定行和指定列,而且返回一個list包裝的object數組
     * 
     * @param sheetNum
     *            sheet的位置號
     * @param startRowNum
     *            開始的行號
     * @param endRowNum
     *            結束的行號
     * @param startCellNum
     *            開始的列號
     * @param endCellNum
     *            結束的列號
     * @param notReadNum
     *            在開始行和結束行之間不用讀的行號
     * @return list包裝的object數組
     */
    public List<Object[]> readListObject(int sheetNum, int startRowNum,
            int endRowNum, int startCellNum, int endCellNum, int... notReadNum) {
        List<Object[]> oList = new ArrayList<Object[]>();
        Sheet sheet = wb.getSheetAt(sheetNum);
        if (endRowNum == -1) {
            endRowNum = sheet.getLastRowNum() + 1;
        } else {
            endRowNum++;
        }
        for (int i = startRowNum; i < endRowNum; i++) {
            Object[] objects = readOneline(sheet, i, startCellNum, endCellNum,
                    notReadNum);
            oList.add(objects);
        }
        return oList;
    }

    /**
     * 讀整個excel
     * 
     * @return 返回一個map,key是sheet的名字,value是每個sheet對應的list
     */
    public Map<String, List<Object[]>> readAllExcel() {
        Map<String, List<Object[]>> map = new HashMap<String, List<Object[]>>();
        int sheetNum = wb.getNumberOfSheets();
        for (int i = 0; i < sheetNum; i++) {
            String sheetName = wb.getSheetName(i);
            List<Object[]> oList = readListObject(i, 0, -1, 0, -1);
            map.put(sheetName, oList);
        }
        return map;
    }

    public Object transferArrayToObject(Class clazz, Object[] objects) {
        try {
            Object object = clazz.newInstance();
            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < objects.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);
                if ((field.getType() == int.class || field.getType() == Integer.class)
                        && (objects[i] instanceof Double)) {
                    System.out.println(objects[i]);
                    Double tempValue = (Double) objects[i];
                    objects[i] = tempValue.intValue();
                }
                field.set(object, objects[i]);
            }
            return object;
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    public Object readOneObjectToBean(Class clazz, int sheetNum, int rowNum,
            int startCellNum, int endCellNum, int... notReadNum) {
        Object[] objectArray = readOneObject(sheetNum, rowNum, startCellNum,
                endCellNum, notReadNum);
        return transferArrayToObject(clazz, objectArray);
    }

    public Object readOneObjectToBean(Class clazz, String sheetName,
            int rowNum, int startCellNum, int endCellNum, int... notReadNum) {
        Object[] objectArray = readOneObject(sheetName, rowNum, startCellNum,
                endCellNum, notReadNum);
        return transferArrayToObject(clazz, objectArray);
    }

    public List readListObjectToBean(Class clazz, int sheetNum,
            int startRowNum, int endRowNum, int startCellNum, int endCellNum,
            int... notReadNum) {
        List<Object[]> oList = readListObject(sheetNum, startCellNum,
                endRowNum, startCellNum, endCellNum, notReadNum);
        List list = new ArrayList();
        for (Object[] objectArray : oList) {
            Object object = transferArrayToObject(clazz, objectArray);
            list.add(object);
        }
        return list;
    }

    public List readListObjectToBean(Class clazz, String sheetName,
            int startRowNum, int endRowNum, int startCellNum, int endCellNum,
            int... notReadNum) {
        List<Object[]> oList = readListObject(sheetName, startCellNum,
                endRowNum, startCellNum, endCellNum, notReadNum);
        List list = new ArrayList();
        for (Object[] objectArray : oList) {
            Object object = transferArrayToObject(clazz, objectArray);
            list.add(object);
        }
        return list;
    }

    public Map<String, List> readAllExcel(Class clazz) {
        Map<String, List<Object[]>> oMap = readAllExcel();
        Map<String, List> map = new HashMap<String, List>();
        for (Entry<String, List<Object[]>> entry : oMap.entrySet()) {
            String key = entry.getKey();
            List<Object[]> oList = entry.getValue();
            List list = new ArrayList();
            for (Object[] objectArray : oList) {
                Object o = transferArrayToObject(clazz, objectArray);
                list.add(o);
            }
            map.put(key, list);
        }
        return map;
    }

    public static void main(String[] args) throws InvalidFormatException,
            IOException {
        POIExcelUtilHelper helper = new POIExcelUtilHelper(
                "D://CR Tracking List_Order_SPEAR v4 final.xlsx");
        Object[] list = helper.readOneObject("CR List", 2, 0, 41, 31, 32);
        System.out.println(Arrays.toString(list));
        System.out.println(list.length);
        System.out.println("read the excel end!");

    }
}
相關文章
相關標籤/搜索