Apache POI和excel操作



<!--添加依賴--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.14</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.14</version> </dependency>

描述

POI結構:

  • HSSF - 提供讀寫Microsoft Excel XLS格式檔案的功能
  • XSSF - 提供讀寫Microsoft Excel OOXML XLSX格式檔案的功能
  • HWPF - 提供讀寫Microsoft Word DOC格式檔案的功能
  • HSLF - 提供讀寫Microsoft PowerPoint格式檔案的功能
  • HDGF - 提供讀Microsoft Visio格式檔案的功能
  • HPBF - 提供讀Microsoft Publisher格式檔案的功能
  • HSMF - 提供讀Microsoft Outlook格式檔案的功能

測試類

package com.study.test;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;

import java.io.IOException;

public class PoiTest01 {
    @Test
    public void test01() throws IOException {
        //1 創建工作簿對象
        XSSFWorkbook workbook = new XSSFWorkbook("G:/hello.xlsx");
        //2 獲得工作表對象
        XSSFSheet sheet = workbook.getSheetAt(0);
        //3 遍歷工作表 獲得行對象
        for (Row row : sheet) {
            //4 遍歷行對象 獲得列對象
            for (Cell cell : row) {
                //5 獲得列里面的內容
                System.out.println(cell.getStringCellValue());
            }
            System.out.println("------------");
        }
        //6.關閉
        workbook.close();
    }
}

 

異常處理

java.lang.IllegalStateException: Cannot get a text value from a numeric cell

 

 

輸出結果:

張三
李四
------------
45
82
------------
89
23
------------

 

一、當我們遇到用“數字”表示的【文本型】內容時,怎么處理

方法一:在輸入這串“數字”之前,先輸入一個英文符號【‘】(也就是輸入法為英文狀態時,輸入一個單引號)。

比如你需要輸入一個信息“0023”,如果你不輸入【’】,直接輸入“0023”,回車后單元格內的信息將顯示的是“23”。

方法二:先選擇這個單元格或這部分單元格,鼠標右擊選中部分,在彈出 的菜單中選【設置單元格格式】,再在彈出的窗口中依次選擇【數字】-【文本】-【確定】,最后輸入”0023“。

經過這樣的操作,你會發現,在單元格的左上角會有一個”小的綠色的三角“符號,表示”這個單元格里的內容被強制轉換成了文本型內容“。

特別適用於:保存身份證號信息、保存0開頭的數字信息。

POI操作Excel表格封裝了幾個核心對象:

XSSFWorkbook:工作簿     XSSFSheet:工作表       Row:行          Cell:單元格

上面案例是通過遍歷工作表獲得行,遍歷行獲得單元格,最終獲取單元格中的值。

還有一種方式就是獲取工作表最后一個行號,從而根據行號獲得行對象,通過行獲取最后一個單元格索引,從而根據單元格索引獲取每行的一個單元格對象,代碼如下

  // 1.創建工作簿對象
        XSSFWorkbook workbook = new XSSFWorkbook("G:/hello.xlsx");
        // 2.獲得工作表對象
        XSSFSheet sheet = workbook.getSheetAt(0);// Excel默認有三個表對象
        // 3.獲得最后一行的行號
        int lastRowNum = sheet.getLastRowNum();
        // 4.遍歷行
        for(int i =0;i<=lastRowNum;i++){
            XSSFRow row = sheet.getRow(i);
            // 5.獲得最后一列的列號
            short lastCellNum = row.getLastCellNum();
            // 6.遍歷列
            for(int j = 0;j<lastCellNum;j++){
                //7.取出數據
                XSSFCell cell = row.getCell(j);
                System.out.println(cell.getStringCellValue());
            }
        }
        // 8.關閉
        workbook.close();

寫數據進入表中

  @Test
    //使用POI可以在內存中創建一個Excel文件並將數據寫入到這個文件,最后通過輸出流將內存中的Excel文件下載到磁盤
    public void fun03() throws Exception {
        //1 創建工作簿對象
        XSSFWorkbook workbook = new XSSFWorkbook();
        //2 創建工作表對象
        XSSFSheet xssfSheet = workbook.createSheet("學生名單");
        //3 創建行
        XSSFRow row01 = xssfSheet.createRow(0);
        //4 創建列,設置內容
        row01.createCell(0).setCellValue("姓名");
        row01.createCell(1).setCellValue("性別");
        row01.createCell(2).setCellValue("地址");
        XSSFRow row02 = xssfSheet.createRow(1);
        row02.createCell(0).setCellValue("張三2");
        row02.createCell(1).setCellValue("1");// 數字字符串插入的是文本格式
        row02.createCell(2).setCellValue("深圳2");
        XSSFRow row03 = xssfSheet.createRow(2);
        row03.createCell(0).setCellValue("李四2");
        row03.createCell(1).setCellValue("1");
        row03.createCell(2).setCellValue("北京2");
        //5.通過輸出流對象寫到磁盤
        FileOutputStream os = new FileOutputStream("G:/student.xlsx");
        workbook.write(os);
        os.flush();
        os.close();
        workbook.close();
    }

結果:

 

 

 

POI工具類

package com.itheima.utils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

public class POIUtils {
    private final static String xls = "xls";
    private final static String xlsx = "xlsx";
    private final static String DATE_FORMAT = "yyyy/MM/dd";
    /**
     * 讀入excel文件,解析后返回
     * @param file
     * @throws IOException
     */
    public static List<String[]> readExcel(MultipartFile file) throws IOException {
        //檢查文件
        checkFile(file);
        //獲得Workbook工作薄對象
        Workbook workbook = getWorkBook(file);
        //創建返回對象,把每行中的值作為一個數組,所有行作為一個集合返回
        List<String[]> list = new ArrayList<String[]>();
        if(workbook != null){
            for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){
                //獲得當前sheet工作表
                Sheet sheet = workbook.getSheetAt(sheetNum);
                if(sheet == null){
                    continue;
                }
                //獲得當前sheet的開始行
                int firstRowNum  = sheet.getFirstRowNum();
                //獲得當前sheet的結束行
                int lastRowNum = sheet.getLastRowNum();
                //循環除了第一行的所有行
                for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){
                    //獲得當前行
                    Row row = sheet.getRow(rowNum);
                    if(row == null){
                        continue;
                    }
                    //獲得當前行的開始列
                    int firstCellNum = row.getFirstCellNum();
                    //獲得當前行的列數
                    int lastCellNum = row.getPhysicalNumberOfCells();
                    String[] cells = new String[row.getPhysicalNumberOfCells()];
                    //循環當前行
                    for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){
                        Cell cell = row.getCell(cellNum);
                        cells[cellNum] = getCellValue(cell);
                    }
                    list.add(cells);
                }
            }
            workbook.close();
        }
        return list;
    }

    //校驗文件是否合法
    public static void checkFile(MultipartFile file) throws IOException{
        //判斷文件是否存在
        if(null == file){
            throw new FileNotFoundException("文件不存在!");
        }
        //獲得文件名
        String fileName = file.getOriginalFilename();
        //判斷文件是否是excel文件
        if(!fileName.endsWith(xls) && !fileName.endsWith(xlsx)){
            throw new IOException(fileName + "不是excel文件");
        }
    }
    public static Workbook getWorkBook(MultipartFile file) {
        //獲得文件名
        String fileName = file.getOriginalFilename();
        //創建Workbook工作薄對象,表示整個excel
        Workbook workbook = null;
        try {
            //獲取excel文件的io流
            InputStream is = file.getInputStream();
            //根據文件后綴名不同(xls和xlsx)獲得不同的Workbook實現類對象
            if(fileName.endsWith(xls)){
                //2003
                workbook = new HSSFWorkbook(is);
            }else if(fileName.endsWith(xlsx)){
                //2007
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return workbook;
    }
    public static String getCellValue(Cell cell){
        String cellValue = "";
        if(cell == null){
            return cellValue;
        }
        //如果當前單元格內容為日期類型,需要特殊處理
        String dataFormatString = cell.getCellStyle().getDataFormatString();
        if(dataFormatString.equals("m/d/yy")){
            cellValue = new SimpleDateFormat(DATE_FORMAT).format(cell.getDateCellValue());
            return cellValue;
        }
        //把數字當成String來讀,避免出現1讀成1.0的情況
        if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
            cell.setCellType(Cell.CELL_TYPE_STRING);
        }
        //判斷數據的類型
        switch (cell.getCellType()){
            case Cell.CELL_TYPE_NUMERIC: //數字
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            case Cell.CELL_TYPE_STRING: //字符串
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case Cell.CELL_TYPE_BOOLEAN: //Boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA: //公式
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case Cell.CELL_TYPE_BLANK: //空值
                cellValue = "";
                break;
            case Cell.CELL_TYPE_ERROR: //故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知類型";
                break;
        }
        return cellValue;
    }
}

復雜execl案例

 /**
     * 導出Excel報表
     * @return
     */
    @RequestMapping("/exportBusinessReport.shtml")
    public Result exportBusinessReport(HttpServletRequest req, HttpServletResponse resp){
        try {
            //遠程調用報表服務獲取報表數據
            List<Map> list = orderService.getBusinessReportData(); // 這是從數據庫獲取到的數據
            //取出結果數據,准備將報表數據寫入到Excel文件中
            //獲取Excel模板文件絕對路徑
            InputStream is = req.getSession().getServletContext().getResourceAsStream("template/report-Template.xlsx");
            //讀取模板對象
            XSSFWorkbook workbook = new XSSFWorkbook(is);
            XSSFSheet sheet = workbook.getSheetAt(0);
            int rowAdd = 0;
            XSSFRow row;
            for (Map map : list) {
                System.out.println("列表數據:" + map);
                String orderId = (String) map.get("orderId");
                String title = (String) map.get("title");
                int num = (int) map.get("num");
                Double totalFee = (Double) map.get("totalFee");
                String status = (String) map.get("status");
                String userId = (String) map.get("userId");
                String sellerId = (String) map.get("sellerId");
                Date createTime = (Date) map.get("createTime");
                row = sheet.getRow(++rowAdd);
                if (row == null) {// 如果單元格為空,就創建單元格,在將數據添加上去,這樣就不需要設置表的單元格的特定格式了
                    row = sheet.createRow(rowAdd);
                }
                if (row.getCell(0)==null){
                    row.createCell(0);
                }
                if (row.getCell(1)==null){
                    row.createCell(1);
                }
                if (row.getCell(2)==null){
                    row.createCell(2);
                }
                if (row.getCell(3)==null){
                    row.createCell(3);
                }
                if (row.getCell(4)==null){
                    row.createCell(4);
                }
                if (row.getCell(5)==null){
                    row.createCell(5);
                }if (row.getCell(6)==null){
                    row.createCell(6);
                }
                if (row.getCell(7)==null){
                    row.createCell(7);
                }


                row.getCell(0).setCellValue(orderId);
                row.getCell(1).setCellValue(title);
                row.getCell(2).setCellValue(num);
                row.getCell(3).setCellValue(totalFee);
                row.getCell(4).setCellValue(status);
                row.getCell(5).setCellValue(userId);
                row.getCell(6).setCellValue(sellerId);
                row.getCell(7).setCellValue(createTime.toLocaleString());
            }
            //通過流輸出進行文件下載
            ServletOutputStream out = resp.getOutputStream();
            resp.setContentType("applicatioon/vnd.ms-excel");
            resp.setHeader("content-Disposition"
                    , "attachment;filename=report.xlsx");
            workbook.write(out);
            out.flush();
            out.close();
            workbook.close();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, "獲取報表失敗");
        }
  <script>
        var app = new Vue({
            el: '#app',
            data:{
                reportDate:'',
                list:[]
            },
            created() {// 展示其execl文檔的做法,就是將list進行循環遍歷, 其后台需要做的就是查詢到,將其傳入list中
                axios.get("/order/getBusinessReportData.shtml").then((res)=>{
                    app.list = res.data;
                    app.reportDate=res.data.reportDate;
                    console.log("_________________________"+app.list);
                });
            },
            methods:{
                exportExcel(){ // 導出文件,前端的做法就是輸出流文件
                    window.location.href = '/report/exportBusinessReport.shtml';
                }
            }
        })
    </script>

前端遍歷的語句

                <div class="box" style="height: 900px">
                    <div class="excelTitle" >
                        <el-button @click="exportExcel">導出Excel</el-button>運營數據統計
                    </div>
                    <div>商家交易統計</div>
                        <!--<td colspan="4" class="headBody">商家交易統計</td>-->

                    <table class="exceTable" cellspacing="0" cellpadding="0" border="1px">

                        <!--1  查詢訂單詳情表 訂單表order_id和訂單詳情表的order_id相同  統計近一個月的訂單  查詢成交最多的商品 成交的總數量 付款情況 -->
                        <tr>
                            <td width="15%" align="center" class="tabletrBg">商品id</td>
                            <td width="20%" align="center"  class="tabletrBg">商品名稱</td>
                            <td width="5%" align="center"  class="tabletrBg">交易數量</td>
                            <td width="10%" align="center" class="tabletrBg">支付金額</td>
                            <td width="10%" align="center"  class="tabletrBg">支付狀態</td>
                            <td width="15%" align="center"  class="tabletrBg">用戶名稱</td>
                            <td width="10%" align="center"  class="tabletrBg">商家名稱</td>
                            <td width="15%" align="center"  class="tabletrBg">創建時間</td>
                        </tr>
             <!--對list進行遍歷-->
                        <tr v-for="entity in list">
                            <td align="center" >{{entity.orderId}}</td>
                            <td align="center" >{{entity.title}}</td>
                            <td align="center" >{{entity.num}}</td>
                            <td align="center" >{{entity.totalFee}}</td>
                            <td align="center" >{{entity.status}}</td>
                            <td align="center" >{{entity.userId}}</td>
                            <td align="center" >{{entity.sellerId}}</td>
                            <td align="center" >{{entity.createTime}}</td>
                        </tr>
                    </table>
                </div>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM