使用POI 操作Excel (創建、寫入數據、設置單元格顏色)

目錄

1、使用場景

2、代碼實現

2.1、pom.xml 之中引入POI的jar

2.2、對已經下載完畢的文件進行檢查並編輯Excel文件,標識未下載完畢的文件

3、成果展現

3.1、創建Excel文件相關結果展示

3.2、比對完畢文件後是否下載標識展示

4、總結

5、參考文章


1、使用場景

        本文章主要記錄如何使用使用POI進行基本的創建Excel文件和讀取Excel文件,同時如何設定Excel文件單元格的樣式。

        因本人在最近一段時間,因爲需要下載百度公有云上的音視頻、文檔文件到本地;然後根據視頻主鍵id,去關聯數據庫之中的記錄。因爲視頻下載完畢後需要上傳的阿里雲上;需要通過唯一主鍵(百度視頻id)、去更新上傳到阿里雲上的視頻id。同時需要記錄下載後的每個視頻文件存儲在計算機磁盤上路徑,然後通過後端Java程序讀取Excel單元格之中文件路徑;然後去通過Aliyun SDK上傳文件到阿里雲上去。於是此處涉及到創建Excel文件,同時需要寫入一下文件基本信息。

      另外需要在下載完畢後,需要檢查一下Excel表格之中那些文件未下載,於是需要針對未下載視頻的id的單元格進行標識。如果此視頻未下載,單元格背景顏色標識爲紅色。    

2、代碼實現

2.1、pom.xml 之中引入POI的jar

<!-- Excel 使用POI操作相關jar start -->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>4.1.1</version>
</dependency>

2.2、使用POI創建和讀取Excel文件

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.util.*;

/**
 * @Classname CreateExcelFile
 * @Description 生產Excel文件 包括(.xls 和 .xlsx)
 * 此類主要兩種不同類型Excel文件的傳統操作方式
 * @Date 2019/11/7 11:54
 * @Created by jianxiapc
 */
public class ExcelXlsOrXlsxOperate {

    /**
     * 判斷文件的sheet是否存在.
     * @param excelSuffixType 文件(.xls 和 .xlsx)
     * @param fileDir   文件路徑
     * @param sheetName  表格索引名
     * @return boolean
     */
    public static boolean excelSheetIsExist(String excelSuffixType,String fileDir, String sheetName){

        boolean flag = false;
        File file = new File(fileDir);
        Workbook workbook=null;
        if (file.exists()) {
            //文件存在,創建workbook
            try {
                if(".xls".equals(excelSuffixType)){
                    workbook = new HSSFWorkbook(new FileInputStream(file));
                }else if(".xlsx".equals(excelSuffixType)){
                    workbook = new XSSFWorkbook(new FileInputStream(file));
                }
                Sheet sheet = workbook.getSheet(sheetName);
                if (sheet!=null) {
                    //文件存在,sheet存在
                    flag = true;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else {
            //文件不存在
            flag = false;
        }
        return flag;
    }

    /**
     * 創建新excel(xls).
     * @param excelSuffixType 文件(.xls 和 .xlsx)
     * @param fileDir excel的路徑
     * @param sheetNames 要創建的表格索引列表
     * @param titleRow  excel的第一行即表格頭
     */
    public static void createExcelFileBySuffix(String excelSuffixType,String fileDir, List<String> sheetNames, String titleRow[]){

        Workbook workbook=null;
        //創建workbook
        if(".xls".equals(excelSuffixType)){
            workbook = new HSSFWorkbook();
        }else if(".xlsx".equals(excelSuffixType)){
            workbook = new XSSFWorkbook();
        }
        //新建文件
        FileOutputStream fileOutputStream = null;
        Row row = null;
        try {

            CellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(HorizontalAlignment.LEFT);
            cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);

            //添加Worksheet(不添加sheet時生成的xls文件打開時會報錯)
            for(int i = 0; i<sheetNames.size(); i++){
                workbook.createSheet(sheetNames.get(i));
                workbook.getSheet(sheetNames.get(i)).createRow(0);
                //添加表頭, 創建第一行
                row = workbook.getSheet(sheetNames.get(i)).createRow(0);
                row.setHeight((short)(20*20));
                for (short j = 0; j < titleRow.length; j++) {

                    Cell cell = row.createCell(j, CellType.BLANK);
                    cell.setCellValue(titleRow[j]);
                    cell.setCellStyle(cellStyle);
                }
                fileOutputStream = new FileOutputStream(fileDir);
                workbook.write(fileOutputStream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 往excel(xls)中寫入(已存在的數據無法寫入).     *
     * @param excelSuffixType 文件(.xls 和 .xlsx)
     * @param fileDir    文件路徑
     * @param sheetName  表格索引
     * @param mapList
     * @throws Exception
     */

    public static void writeToExcelFileBySuffix(String excelSuffixType,String fileDir, String sheetName, List<Map<String,String>> mapList) throws Exception{

        //創建workbook
        File file = new File(fileDir);
        Workbook workbook=null;

        try {
            //創建workbook
            if(".xls".equals(excelSuffixType)){
                workbook = new HSSFWorkbook(new FileInputStream(file));
            }else if(".xlsx".equals(excelSuffixType)){
                workbook = new XSSFWorkbook(new FileInputStream(file));
            }
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }

        //文件流
        FileOutputStream fileOutputStream = null;
        Sheet sheet = workbook.getSheet(sheetName);
        // 獲取表格的總行數
        // int rowCount = sheet.getLastRowNum() + 1; // 需要加一
        //獲取表頭的列數
        int columnCount = sheet.getRow(0).getLastCellNum();

        try {
            // 獲得表頭行對象
            Row titleRow = sheet.getRow(0);
            //創建單元格顯示樣式
            CellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setAlignment(HorizontalAlignment.LEFT);
            cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);


            if(titleRow!=null){
                for(int rowId = 0; rowId < mapList.size(); rowId++){
                    Map<String,String> map = mapList.get(rowId);
                    Row newRow=sheet.createRow(rowId+1);
                    newRow.setHeight((short)(20*20));//設置行高  基數爲20

                    for (short columnIndex = 0; columnIndex < columnCount; columnIndex++) {  //遍歷表頭
                        //trim()的方法是刪除字符串中首尾的空格
                        String mapKey = titleRow.getCell(columnIndex).toString().trim();
                        Cell cell = newRow.createCell(columnIndex);
                        cell.setCellStyle(cellStyle);
                        cell.setCellValue(map.get(mapKey)==null ? null : map.get(mapKey).toString());
                    }
                }
            }

            fileOutputStream = new FileOutputStream(fileDir);
            workbook.write(fileOutputStream);
        } catch (Exception e) {
            throw e;
        } finally {
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

        //String excelSuffix=".xls";
        //String fileDir = "d:\\workbook.xls";

        String excelSuffix=".xlsx";
        String fileDir = "d:\\workbook.xlsx";
        List<String> sheetName = new ArrayList<>();

        sheetName.add("A");
        sheetName.add("B");
        sheetName.add("C");

        System.out.println(sheetName);

        String[] title = {"id","name","password"};
        createExcelFileBySuffix(excelSuffix,fileDir, sheetName, title);

        List<Map<String,String>> userList1 = new ArrayList<Map<String,String>>();
        Map<String,String> map=new HashMap<String,String>();
        map.put("id", "111");
        map.put("name", "張三");
        map.put("password", "111!@#");

        Map<String,String> map2=new HashMap<String,String>();
        map2.put("id", "222");
        map2.put("name", "李四");
        map2.put("password", "222!@#");

        Map<String,String> map3=new HashMap<String,String>();
        map3.put("id", "33");
        map3.put("name", "王五");
        map3.put("password", "333!@#");
        userList1.add(map);
        userList1.add(map2);
        userList1.add(map3);

        Map<String, List<Map<String, String>>> users = new HashMap<>();

        users.put("A", userList1);

        List<Map<String,String>> userList2 = new ArrayList<Map<String,String>>();
        Map<String,String> map4=new HashMap<String,String>();
        map4.put("id", "111");
        map4.put("name", "張三");
        map4.put("password", "111!@#");

        Map<String,String> map5=new HashMap<String,String>();
        map5.put("id", "222");
        map5.put("name", "李四");
        map5.put("password", "222!@#");

        Map<String,String> map6=new HashMap<String,String>();
        map6.put("id", "33");
        map6.put("name", "王五");
        map6.put("password", "333!@#");
        userList2.add(map4);
        userList2.add(map5);
        userList2.add(map6);

        users.put("B", userList2);

        List<Map<String,String>> userList3 = new ArrayList<Map<String,String>>();

        users.put("C", userList3);
        System.out.println(sheetName.size());
        //刪除List 集合中特定的元素
        for(Iterator<String> sheeNameIterator = sheetName.iterator();sheeNameIterator.hasNext();){

            String sheet = sheeNameIterator.next();
            //此時刪除了第三張sheet
            if ( users.get(sheet).size() == 0) {

                sheeNameIterator.remove();

            }
        }

        System.out.println(sheetName.size());
        createExcelFileBySuffix(excelSuffix,fileDir, sheetName, title);
        for (int j = 0; j < sheetName.size(); j++) {
            try {
                writeToExcelFileBySuffix(excelSuffix,fileDir, sheetName.get(j), users.get(sheetName.get(j)));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2.2、對已經下載完畢的文件進行檢查並編輯Excel文件,標識未下載完畢的文件

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;

public class CheckFilesIsDownloadedUtils {

    /**
     *
     * @param excelFilePath
     * @param passCheckFileMovePath
     */
    public static void checkFileIsDownloadedByIdMarkExcelRowColor(String excelFilePath,String passCheckFileMovePath) throws FileNotFoundException, IOException {
        Workbook wb = null;
        String extName = ".xls";
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(excelFilePath);
            if (".xls".equals(extName)) {
                wb = new HSSFWorkbook(fis);
            } else if (".xlsx".equals(extName)) {
                wb = new XSSFWorkbook(fis);
            } else {
                // 無效後綴名稱,這裏之能保證excel的後綴名稱,不能保證文件類型正確,不過沒關係,在創建Workbook的時候會校驗文件格式
                throw new IllegalArgumentException("Invalid excel version");
            }
            // 生成一個樣式
            CellStyle cellStyle = wb.createCellStyle();
            cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);//填充單元格
            cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); // 設置邊界的類型單元格的左邊框
            cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
            cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
            cellStyle.setFillForegroundColor(HSSFColor.RED.index); //填紅色
            //1、讀取Excel行之中的文件id 通過id去判斷文件名之中是否包含 如果包含則移動到通過檢查路基下
            Sheet sheet = wb.getSheetAt(0);
            // 解析sheet
            int rowCount = sheet.getLastRowNum()+1;
            // 解析sheet 的行
            for (int j = 1; j < rowCount; j++) {
                HSSFRow row = (HSSFRow) sheet.getRow(j);
                if (row == null || null == row.getCell(0) || null == row.getCell(1)) {
                    continue;
                }
                if (row.getFirstCellNum() < 0) {
                    continue;
                }
                String vodeId = row.getCell(0).toString();
                String vodeSrcPath = row.getCell(1).toString();
                //打印不存在的文件
                //PrintStream ps = new PrintStream("g:/log.txt");
                //System.setOut(ps);
                File notfile = new File(vodeSrcPath);
                String vodeName = notfile.getName();
                if(!notfile.exists()) {
                    System.out.println("視頻文件:"+vodeId+" 不存在 "+vodeName);
                    row.getCell(0).setCellStyle(cellStyle);
                    //System.out.println("內容值: "+row.getCell(0).toString());
                    fos = new FileOutputStream(excelFilePath);
                    wb.write(fos);
                }else{
                    //2、否則沒有則標記Excel行的顏色(red)爲未下載的
                    moveFile(vodeSrcPath,passCheckFileMovePath);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
            }
        }
    }
    /**
     * 移動文件
     * @param srcPath
     * @param endPath
     */
    public  static void moveFile(String srcPath,String endPath){
        try{
            File file=new File(srcPath); //源文件
            File tmpFile = new File(endPath);//獲取文件夾路徑
            if(!tmpFile.exists()){//判斷文件夾是否創建,沒有創建則創建新文件夾
                tmpFile.mkdirs();
            }
            if (file.renameTo(new File(endPath+file.getName()))) //源文件移動至目標文件目錄
            {
                System.out.println("File is moved successful!");//輸出移動成功
            }
            else
            {
                System.out.println("File is failed to move !");//輸出移動失敗
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        String excelFilePath="D:\\CheckVideoFiles\\jungangP151-217-6660.xls";
        String passCheckFileMovePath="d:\\CheckVideoFiles\\PassVideoFiles\\";
        checkFileIsDownloadedByIdMarkExcelRowColor(excelFilePath,passCheckFileMovePath);
    }
}

3、成果展現

3.1、創建Excel文件相關結果展示

3.2、比對完畢文件後是否下載標識展示

4、總結

     希望通過本文章能夠針對使用POI基本操作能夠有一個基本的認識,並且能夠結合實際工作之中能夠使用。

Workbook wb=WorkbookFactory.create(new FileInputStream(file));//可以讀取xls格式或xlsx格式。

使用此種方式需注意close();問題,建議使用顯性創建。

現在Alibaba已經開源了一個EasyExcel,這個性能更加優越。後續文章將介紹相關使用。

5、參考文章

使用poi創建Excel文件

原生poi生成Excel

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章