1. 程式人生 > >java 對excel 模板的讀取,寫入值操作

java 對excel 模板的讀取,寫入值操作

自己的備忘錄

jar包不一定全部都要

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.15</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
<version>3.15</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId> <version>1.6</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.9</version> </dependency> <dependency>
<groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.2</version> </dependency>
@Data
public class ExcelNode {
    private int sheet; //sheet頁
    // 第一個map key 是 row 多少行,第二個map key是cell 多少列,vlaue 是值
private Map<Integer,Map<Integer,String>> value;
//設定多個sheet頁,第一個map key 是sheet頁,第二個map key 是 row 多少行,第三個map key是cell 多少列,vlaue 是值
private Map<Integer, Map<Integer,Map<Integer,String>>> setSheets;
}

因為模板在專案裡,所以這樣讀,如果要讀磁碟上的可以這樣

String filePath = "C:\\Users\\Administrator\\Desktop\\1.xlsx";
File file = new File(filePath);
XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(file));
import com.fangfa.jiliang.dto.ExcelNode;
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.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
 * 對excel 模板讀取,寫入值操作
 * @author green
 * @date 2018/6/14/014
 */
public class ExcelUtil {

   /**
    * 寫入excel模板,對單個sheet頁
    *@author  gl
    *@date    2018/6/14/014
    *@param
*@return
*/
public static Workbook writeExcelBySingletSheet(String templatePath, ExcelNode excelNode){
        String end = templatePath.substring(templatePath.lastIndexOf("."),templatePath.length());
        if(end.equalsIgnoreCase("xls")){
            return writeToExcelBySingletSheetEndXls(templatePath,excelNode);
}else {
            return writeToExcelBySingletSheetEndXlsx(templatePath,excelNode);
}
    }

    /**
     * 寫入excel模板,對多個sheet頁
     *@author  gl
     *@date    2018/6/14/014
     *@param
*@return
*/
public static Workbook writeExcelByMoreSheet(String templatePath, ExcelNode excelNode){
        String end = templatePath.substring(templatePath.lastIndexOf("."),templatePath.length());
        if(end.equalsIgnoreCase("xls")){
            return writeToExcelByMoreSheetEndXls(templatePath,excelNode);
}else {
            return writeToExcelByMoreSheetEndXlsx(templatePath,excelNode);
}
    }



    /**
     * 寫入excel模板,對單個sheet頁寫入,主要在使用之前一定要,使用printExcel方法,(在最下面)
     * 檢查一下你要替換的內容在那個部位;該方法只能用於 .xlsx 結尾的
     *@author  gl
     *@date    2018/6/14/014
     *@param templatePath:是檔案模板路徑,excelNode 資料物件
     *@return
*/
public static XSSFWorkbook writeToExcelBySingletSheetEndXlsx(String templatePath, ExcelNode excelNode){
        try {
            InputStream in = UploadAndDownloadUtil.class.getClassLoader().getResourceAsStream(templatePath);
XSSFWorkbook workbook = new XSSFWorkbook(in);
XSSFSheet sheet = workbook.getSheetAt(excelNode.getSheet());
excelNode.getValue().forEach( (k,v) -> {
                XSSFRow row = sheet.getRow(k);
v.forEach( (k1,v1) -> {
                    row.getCell(k1).setCellValue(v1);
});
});
            return workbook;
} catch (IOException e) {
            e.printStackTrace();
}
        return null;
}

    /**
     * 寫入excel模板,對多個sheet頁寫入,該方法只能用於 .xlsx 結尾的
     *@author  gl
     *@date    2018/6/14/014
     *@param
*@return
*/
public static XSSFWorkbook writeToExcelByMoreSheetEndXlsx(String templatePath, ExcelNode excelNode){
        try {
            InputStream in = UploadAndDownloadUtil.class.getClassLoader().getResourceAsStream(templatePath);
XSSFWorkbook workbook = new XSSFWorkbook(in);
excelNode.getSetSheets().forEach((k,v)->{
                XSSFSheet sheet = workbook.getSheetAt(k);
v.forEach( (k1,v1) -> {
                    XSSFRow row = sheet.getRow(k1);
v1.forEach( (k2,v2) -> {
                        row.getCell(k2).setCellValue(v2);
});
});
});
            return workbook;
} catch (IOException e) {
            e.printStackTrace();
}
        return null;
}


    /**
     * 該方法只能用於 .xls 結尾的
     *@author  gl
     *@date    2018/6/14/014
     *@param templatePath:是檔案模板路徑,excelNode 資料物件
     *@return
*/
public static HSSFWorkbook writeToExcelBySingletSheetEndXls(String templatePath, ExcelNode excelNode){
        try {
            InputStream in = UploadAndDownloadUtil.class.getClassLoader().getResourceAsStream(templatePath);
HSSFWorkbook workbook = new HSSFWorkbook(in);
HSSFSheet sheet = workbook.getSheetAt(excelNode.getSheet());
excelNode.getValue().forEach( (k,v) -> {
                HSSFRow row = sheet.getRow(k);
v.forEach( (k1,v1) -> {
                    row.getCell(k1).setCellValue(v1);
});
});
            return workbook;
} catch (IOException e) {
            e.printStackTrace();
}
        return null;
}

    /**
     * 寫入excel模板,對多個sheet頁寫入,該方法只能用於 .xls 結尾的
     *@author  gl
     *@date    2018/6/14/014
     *@param
*@return
*/
public static HSSFWorkbook writeToExcelByMoreSheetEndXls(String templatePath, ExcelNode excelNode){
        try {
            InputStream in = UploadAndDownloadUtil.class.getClassLoader().getResourceAsStream(templatePath);
HSSFWorkbook workbook = new HSSFWorkbook(in);
excelNode.getSetSheets().forEach((k,v)->{
                HSSFSheet sheet = workbook.getSheetAt(k);
v.forEach( (k1,v1) -> {
                    HSSFRow row = sheet.getRow(k1);
v1.forEach( (k2,v2) -> {
                        row.getCell(k2).setCellValue(v2);
});
});
});
            return workbook;
} catch (IOException e) {
            e.printStackTrace();
}
        return null;
}
    public static void checkRowCell(XSSFCell cell, int i, int j) {
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                System.out.println(cell.getRichStringCellValue().getString() + "="+i+":"+j);
                break;
            case Cell.CELL_TYPE_NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    System.out.println(String.valueOf(cell.getDateCellValue()) + "="+i+":"+j);
} else {
                    System.out.println(cell.getNumericCellValue() + "="+i+":"+j);
}
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                System.out.println(cell.getBooleanCellValue() + "="+i+":"+j);
                break;
            default:
        }
    }

    public static void printExcel(String path) throws IOException {
        File file = new File(path);
XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(file));
XSSFSheet sheet = wb.getSheetAt(0);
        int rowcount = sheet.getLastRowNum() - sheet.getFirstRowNum();
        int rowcount1 = sheet.getPhysicalNumberOfRows();
System.out.println(rowcount1);
System.out.println("該excle的總行數為:" + (rowcount + 1) + "行 !");
        for (int i = 0; i < rowcount + 1; i++) {
            Row row = sheet.getRow(i);
            if (row != null) {
                for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
                    XSSFCell cell = (XSSFCell) row.getCell(j);
                    if (cell != null) {
                        ExcelUtil.checkRowCell(cell,i,j);
}
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        printExcel("C:\\Users\\Administrator\\Desktop\\1.xlsx");
}
}

為什麼要先把行列讀出來呢?

在有些複雜的excel,有很多合併,行列並不是眼睛看上去的那樣,先讀出來在來對應