Java poi讀取,寫入Excel,處理row和cell可能為空的情況

来源:http://www.cnblogs.com/sunnyroot/archive/2016/08/28/5814905.html
-Advertisement-
Play Games

首先需要導入包 然後寫方法,由於我使用的框架全部是spring 此處我只寫入實現層和控制層代碼 其中有個selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, ...


首先需要導入包

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

然後寫方法,由於我使用的框架全部是spring

此處我只寫入實現層和控制層代碼

@Override
    public InputStream loadMatComYearPlanXls(String MAT_NO_, String MAT_DESC_, Integer MAT_TYPE_, String MAT_SPEC_CAT_CODE_, String COM_CODE_, String DEPT_CODE_, Integer YEAR_, Integer MONTH_, String MAT_BUDGET_CAT_ID_, String MAT_YEAR_PLN_BATCH_ID_, Map<String, Object> operator) {
        NPOIFSFileSystem fs = null;
        Workbook workbook = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        try {
            File file = new File(this.getClass().getResource("/../../resource/matComYearPlan.xls").getFile());
            FileInputStream inputStream = new FileInputStream(file);
            fs = new NPOIFSFileSystem(inputStream);
            workbook = (Workbook) new HSSFWorkbook(fs.getRoot(), true);

            Sheet sheet = workbook.getSheetAt(0);

            List<Map<String, Object>> matYearPlanList = selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, 1, -1, operator);
            List<Map<String, Object>> matTypedmCodeList = dmCodeService.selectDmCodeByGroupName("MAT_TYPE_", operator);
            List<Map<String, Object>> processStatusTypedmCodeList = dmCodeService.selectDmCodeByGroupName("PROCESS_STATUS_TYPE_", operator);
            List<Map<String, Object>> matBudgetCatList = matBudgetCatService.selectMatBudgetCat(1, -1, operator);
            List<Map<String, Object>> matSpecCatList = matSpecCatService.selectMatSpecCat(1, -1, operator);

            Map<String, Object> matYearPlan;
            String MAT_BUDGET_CAT_NAME_ = "";
            String PARENT_MAT_BUDGET_CAT_ID_;
            for (int i = 0; i < matYearPlanList.size(); i++) {
                matYearPlan = matYearPlanList.get(i);
                Row row = sheet.createRow(i + 1);

                row.createCell(0).setCellValue((String) matYearPlan.get("MAT_NO_"));
                row.createCell(1).setCellValue((String) matYearPlan.get("MAT_DESC_"));
                row.createCell(2).setCellValue((String) matYearPlan.get("LARGE_MAT_CAT_CODE_"));
                row.createCell(3).setCellValue((String) matYearPlan.get("UNIT_"));

                if (matYearPlan.get("PLANNED_PRICE_") != null) {
                    row.createCell(4).setCellValue(((BigDecimal) matYearPlan.get("PLANNED_PRICE_")).doubleValue());
                }
                if (matYearPlan.get("AMOUNT_") != null) {
                    row.createCell(5).setCellValue(((BigDecimal) matYearPlan.get("AMOUNT_")).doubleValue());
                }
                if (matYearPlan.get("PLANNED_PRICE_") != null && matYearPlan.get("AMOUNT_") != null) {
                    row.createCell(6).setCellValue(((BigDecimal) matYearPlan.get("PLANNED_PRICE_")).doubleValue() * ((BigDecimal) matYearPlan.get("AMOUNT_")).doubleValue());
                }
                if (matYearPlan.get("MAT_TYPE_") != null) {
                    for (int j = 0; j < matTypedmCodeList.size(); j++) {
                        Map<String, Object> matTypedmCode = matTypedmCodeList.get(j);
                        if ((((BigDecimal) matYearPlan.get("MAT_TYPE_")).intValue()) == (((BigDecimal) matTypedmCode.get("CODE_"))).intValue()) {
                            row.createCell(7).setCellValue((String) matTypedmCode.get("VALUE_"));
                            break;
                        }
                    }
                }
                row.createCell(8).setCellValue((String) matYearPlan.get("DEPT_NAME_"));

                for (int j = 0; j < matBudgetCatList.size(); j++) {
                    Map<String, Object> matBudgetCat = matBudgetCatList.get(j);
                    if (((String) matYearPlan.get("MAT_BUDGET_CAT_ID_")).equals((String) matBudgetCat.get("MAT_BUDGET_CAT_ID_"))) {
                        MAT_BUDGET_CAT_NAME_ = (String) matBudgetCat.get("MAT_BUDGET_CAT_NAME_");
                        PARENT_MAT_BUDGET_CAT_ID_ = (String) matBudgetCat.get("PARENT_MAT_BUDGET_CAT_ID_");
                        while (PARENT_MAT_BUDGET_CAT_ID_ != null) {
                            for (int k = 0; k < matBudgetCatList.size(); k++) {
                                matBudgetCat = matBudgetCatList.get(k);
                                if (PARENT_MAT_BUDGET_CAT_ID_.equals((String) matBudgetCat.get("MAT_BUDGET_CAT_ID_"))) {
                                    MAT_BUDGET_CAT_NAME_ = (String) matBudgetCat.get("MAT_BUDGET_CAT_NAME_") + "/" + MAT_BUDGET_CAT_NAME_;
                                    PARENT_MAT_BUDGET_CAT_ID_ = (String) matBudgetCat.get("PARENT_MAT_BUDGET_CAT_ID_");
                                    break;
                                }
                            }
                        }
                        row.createCell(9).setCellValue("/" + MAT_BUDGET_CAT_NAME_ + "/");
                        break;
                    }
                }
                if (matYearPlan.get("MAT_SPEC_CAT_CODE_") != null) {
                    for (int j = 0; j < matSpecCatList.size(); j++) {
                        Map<String, Object> matSpecCat = matSpecCatList.get(j);
                        if (((String) matYearPlan.get("MAT_SPEC_CAT_CODE_")).equals((String) matSpecCat.get("CODE_"))) {
                            row.createCell(10).setCellValue((String) matSpecCat.get("VALUE_"));
                            break;
                        }
                    }
                }
                if (matYearPlan.get("PROCESS_STATUS_") != null) {
                    for (int j = 0; j < processStatusTypedmCodeList.size(); j++) {
                        Map<String, Object> processStatusTypedmCode = processStatusTypedmCodeList.get(j);
                        if ((((BigDecimal) matYearPlan.get("PROCESS_STATUS_")).intValue()) == (((BigDecimal) processStatusTypedmCode.get("CODE_")).intValue())) {
                            row.createCell(11).setCellValue((String) processStatusTypedmCode.get("VALUE_"));
                            break;
                        }
                    }
                }
            }

            workbook.write(baos);
            baos.flush();
            byte[] bytes = baos.toByteArray();

            return new ByteArrayInputStream(bytes, 0, bytes.length);
        }
        catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        finally {
            try {
                fs.close();
                workbook.close();
                baos.close();
            }
            catch (IOException e) {
            }
        }
    }

其中有個selectMatYearPlan(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, 1, -1, operator);方法是我的業務方法,可根據需要改變自己實際的參數,對自己的代碼進行修改

 Row row = sheet.createRow(i + 1);
 row.createCell(0).setCellValue((String) matYearPlan.get("MAT_NO_"));
這兩句代碼是與其他人不同的地方,有些人的代碼是getRow(),getCell()。那樣很可能會報空指針異常,如果以前有數據只是對其覆蓋可以使用,如果以前沒有數據,是動態生成的最後使用create方法

另外我在代碼中大量使用了String造型,而不是toString()方法,因為String相對於tostring()方法更安全,而其不會報空指針異常。而toString()方法有時會需要重寫,不是那麼安全。
=null.toString()會有空指針異常,而 =(String)null則不會。
//控制層代碼
@RequestMapping(value = "loadMatComYearPlanXls")
    public void loadMatComYearPlanXls(String MAT_NO_, String MAT_DESC_, Integer MAT_TYPE_, String MAT_SPEC_CAT_CODE_, String COM_CODE_, String DEPT_CODE_, Integer YEAR_, Integer MONTH_, String MAT_BUDGET_CAT_ID_, String MAT_YEAR_PLN_BATCH_ID_, HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        try {
            Map<String, Object> operator = getOperator(session);

            InputStream inputStream = matYearPlanService.loadMatComYearPlanXls(MAT_NO_, MAT_DESC_, MAT_TYPE_, MAT_SPEC_CAT_CODE_, COM_CODE_, DEPT_CODE_, YEAR_, MONTH_, MAT_BUDGET_CAT_ID_, MAT_YEAR_PLN_BATCH_ID_, operator);
            response.reset();
            String fileName = URLEncoder.encode("廠礦年計劃表.xls", "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            ServletOutputStream out = response.getOutputStream();
            byte[] content = new byte[65535];
            int length = 0;
            if (inputStream != null) {
                while ((length = inputStream.read(content)) != -1) {
                    out.write(content, 0, length);
                }
            }
            out.flush();
            out.close();
        }
        catch (Exception e) {
            insertBizLog("業務", "MatYearPlanController.loadMatComYearPlanXls", null, null, null, null, null, 1, e.getMessage(), request, session);
            logger.error(e.getMessage(), e);
        }
        insertBizLog("業務", "MatYearPlanController.loadMatComYearPlanXls", null, null, null, null, null, 0, null, request, session);
    }

控制層主要是調用實現層代碼。主要的POI代碼在實現層,網上有很多這類代碼,只是我自己對空指針的處理做了自己的改變,網路上說的很多方法不全。

另外這這次的業務實現里,有個BigDecimal類型,http://baike.baidu.com/link?url=abJmNaoqJGE0RbYpjmOCB4otjPPqhpwYPSlMkVwPV6c_0V8I42VljBvaDtCI6h-xNIn5N5CFjrWPvvz4A132lK

由於將值放進map時都是Object類型,但在取出時,它的類型並沒有丟失,所以在.intValue(),和.doubleValue()取值時,與String不同,同時需要做空值處理

如果不想使用造型可以使用parse解析。

中間有段代碼是做的樹形的迴圈遞歸遍歷。

//在jsp頁面的調用
function _loadMatComYearPlanXls() {
        var MAT_BUDGET_CAT_ID_ = '';
        var records = Ext.getCmp('matBudgetCatPanel').getSelectionModel().getSelection();
        if (records.length != 0) {
            MAT_BUDGET_CAT_ID_ = records[0].get('MAT_BUDGET_CAT_ID_');
        }
        window.open('loadMatComYearPlanXls.do?YEAR_=' + Ext.getCmp('YEAR_').getSubmitValue() + '&MONTH_=' + Ext.getCmp('MONTH_').getSubmitValue() + '&MAT_TYPE_=' + Ext.getCmp('MAT_TYPE_').getSubmitValue() + '&MAT_YEAR_PLN_BATCH_ID_=' + Ext.getCmp('MAT_YEAR_PLN_BATCH_ID_').getSubmitValue() + '&DEPT_CODE_=' + Ext.getCmp('DEPT_CODE_').getSubmitValue() + '&MAT_NO_=' + Ext.getCmp('MAT_NO_').getSubmitValue() + '&MAT_DESC_=' + Ext.getCmp('MAT_DESC_').getSubmitValue() + '&MAT_SPEC_CAT_CODE_=' + Ext.getCmp('MAT_SPEC_CAT_CODE_').getSubmitValue() + '&COM_CODE_=' + COM_CODE_ + '&MAT_BUDGET_CAT_ID_=' + MAT_BUDGET_CAT_ID_, '_blank', 'width=40,height=30,resizable=yes,scrollbars=yes');
    }

JSP頁面只是調用控制層代碼,如果自己有需要,可以按自己的方法傳參調用。

 

 poi的API文檔:http://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.html#SXSSFWorkbook(org.apache.poi.xssf.usermodel.XSSFWorkbook)

歡迎大家閱覽,多多評論其中的不足!!

為工程師之路添磚加瓦!!

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 由於使用DriverManager獲取資料庫連接時,由於DriverManager實現類中有一段靜態代碼塊,可以直接註冊驅動,且可以同時管理多個驅動程式 所以當換資料庫連接時需要指定不同的資料庫,那麼就需要反覆修改properties配置文件(雖然並不麻煩),所以我想將每種驅動連接程式的proper ...
  • 數組對每門編程語言都是重要的數據結構之一,java語言提供的數組是用來儲存固定大小的同類型元素的。 當你需要保存一組數據類型相同的變數或者對象時,我們不可能給每個變數都定義一個變數名,這樣的操作會使代碼臃腫、工作量大且無意義。這時我們就需要數組來保存這些數據。數組根據需要的不同分為一維數,二維數組和 ...
  • 先看一下文件,在當前包下有一個properties配置文件,在根目錄下有一個lib文件夾,裡面放的是mySql的驅動jar包 Driver :是一個介面,資料庫廠商必須提供實現的介面,能從其中獲取資料庫連接 可以通過Driver的實現類的對象獲取資料庫連接 * 1.加入mySql驅動 * 1.1 解 ...
  • 一、MyBaris簡介 1)MyBaris發展過程 MyBatis的前身叫iBatis,本是apache的一個開源項目, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis。 MyBatis是支持普通SQL查詢,存儲過程 ...
  • (一) 接需求 : 需求相關 (貼圖 ) 生成三核對文件 1、新增三核對菜單頁面中,增加生成三核對文件功能按鈕,彈窗可根據變電站、電壓等級查詢定值單。 2、定值單信息以表格形式展示,根據選擇情況,生成三核對文件。 整體就是這樣的一個需求,分sheet,合併單元格,設置各種單元格格式,要有序號。 (二 ...
  • Mybatis是輕量級的持久化框架,的確上手非常快. Mybatis大體上的思路就是由一個總的config文件配置全局的信息,比如mysql連接信息等。然後再mapper中指定查詢的sql,以及參數和返回值。 在Service中直接調用這個mapper即可。 依賴的jar包 主要的mybatis配置 ...
  • ...
  • JPA規範推薦使用Annotation來管理實體類與數據表之間的映射關係,從而避免同時維護兩份文件(Java 實體類 和 XML 映射文件),將映射信息(寫在Annotation中)與實體類集中在一起。 以下我將使用eclipse來構建一個簡單使用註解取代*.hbm.xml的查詢小例子。(p.s 建 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...