1. 程式人生 > >Java通過Poi的開發Excel匯入匯出和下載功能

Java通過Poi的開發Excel匯入匯出和下載功能

原文連結:http://www.zjhuiwan.cn/toDetail?articleId=1812131133133410000

最近有用到Excel的下載、匯入、匯出功能。提供一個Excel模板給使用者下載,使用者根據規範填寫模板然後再匯入Excel資料,儲存到資料庫,也可匯出類表資料為Excel。因為有時候頁面新增功太麻煩,就做成這樣的Excel批量匯入。

154466968004240052054.png

154466968512245091885.png

Excel的下載

這專案用的是spring+Struts2+mybatis。

需要的jar包

1

2

3

4

5

6

<!-- POI-EXCEL -->

<dependency>

  <groupId>org.apache.poi</groupId>

   <artifactId>poi</artifactId>

  <version>3.9</version>

</dependency>

有兩種方式

第一種、把Excel模板放在專案目錄,提供下載。(這種比較方便)

Excel的路徑:webapp/common/excelModule/downloadModel.xlsx。

前臺程式碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<form action="" name="Form" id="myForm" method="" enctype="multipart/form-data">

    <div id="zhongxin">

    <table style="width:95%;" >

           <tr>

          <td style="padding-top: 20px;"><input type="file" id="excel"/></td>

      </tr>

      <tr>

         <td style="text-align: center;padding-top: 10px;">

        <a class="btn btn-mini btn-primary" id="submitBtn">匯入</a>

        <a class="btn btn-mini btn-success" id="downLoadExcel">下載模版</a>

         </td>

       </tr>

      </table>

  </div>

  <div id="zhongxin2"class="center" style="display:none"><br/><img src="images/jzx.gif"/>

  <br/><h4 class="lighter block green"></h4></div> 

</form>

js程式碼:

1

2

3

$('#downLoadExcel').click(function(){

    location.href ='downLoadModel.action'

});

action程式碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

    /**

     * 下載檔案的檔名和流

     */

    private String fileName;

    private InputStream is;

     

   略:get set方法。

     

    /**

     * 下載模板

     

     * @throws Exception

     */

    public String downLoadModel() throws Exception {

 

        // 為InputStream的is流引數賦值

        is = ServletActionContext.getServletContext()

        .getResourceAsStream("/common/excelModule/downloadModel.xlsx");

        fileName = new String("題目匯入模板.xlsx".getBytes(), "ISO8859-1");

 

        return "success";

    }

Struts2配置檔案:

1

2

3

4

5

6

7

8

9

10

<action name="*Question" class="com.bayan.keke.action.QuestionAction"

    method="{1}">

    <result name="toList">/WEB-INF/jsp/question/questionList.jsp</result>

    <result name="success" type="stream">

        <param name="contentType">application/vnd.ms-excel</param>

        <param name="contentDisposition">attachment;fileName=${fileName}</param>

        <param name="inputName">is</param>

        <param name ="bufferSize">4096</param>  

    </result>

</action>

好了,一個簡單的下載功能就完成了。

注意:Struts的配置檔案中的檔名和流要和action的對應。

 

第二種、自定義生成Excel模板,提供下載。(ExcelUtil工具類程式碼在底下)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

/**

     * 下載模板

     

     * @throws Exception

     */

    public void downExcel() throws Exception {

 

        try {

            String[] titles =

                new String[] {"比賽名稱""報名者姓名""報名者手機號"

                "報名者身份證號""性別""郵箱""住址""職業""分數"};

            String[] cols =

                new String[] {"partyName""userName""userPhone",

                 "userIdCard""sex""email",

                    "address""career""score"};

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

         ExcelUtil.outPutExcelByMap(list, titles, cols, "題目資訊模板",

          getRequest(), getResponse());

            renderNull();

        catch (Exception e) {

            e.printStackTrace();

        }

        toList();

 

    }

 

Excel的匯入

 

js程式碼:通過ajax,formdata格式提交檔案

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

//匯入Excel

        $("#importExcel").click(function(){

            $('#importQuestion').modal('show'); 

        });

         

        $("#submitBtn").click(function(){

            var fileName = $("#excel").val();

            var suffix = (fileName.substr(fileName.lastIndexOf("."))).toUpperCase();

             

            //驗證檔案字尾名

            if(".XLS" != suffix && ".XLSX" != suffix ){

                alert("檔案格式只能是.XLS或者.XLSL");

                return false;

            }

            var formData = new FormData();

            var file = $("#excel")[0].files[0];

            if (file != "") {

                formData.append("excel", file);

            }

              $.ajax({

                    type : "POST",

                    url : "importExcel.action",

                    data : formData,

                    cache : false,

                    processData : false,

                    contentType : false,

                    dataType:'json',  

                    success : function(data) {

                        if (data.result == "success") {

                            alert("匯入題目成功");

                             

                            $('#importQuestion').modal('hide');

                            getQuestionList();

                        }else if(data.result == "fileNull"){

                            alert("匯入的檔案為空");

                        }else if(data.result == "excelNull"){

                            alert("匯入的Excel表格內容為空");

                        }else if(data.result == "maxLength"){

                            alert("匯入的Excel表格內容超過了最大1000");

                        else if(data.result == "fail"){

                            alert("匯入資料庫失敗");

                        }else if(data.result=="error"){

                            alert(data.codeError);

                        }else{

                            alert("匯入失敗");

                        }

                         

                    }

                });

            //$("#myForm").submit();

         

        });

action程式碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

/**

     * 匯入Excel

     

     * @throws Exception

     */

    @SuppressWarnings("unused")

    public void importExcel() throws Exception {

        printStartLog("方法開始update", LOGGER);

        // 將客戶端的檔案上傳到服務端

        String desPath = ServletActionContext.getServletContext()

                .getRealPath("/upload/questionModel");

        File destFile = new File(excelFileName);

        // 上傳到本地

        FileUtils.copyFile(excel, destFile);

 

        JSONObject json = new JSONObject();

        if (destFile == null) {

            printDebugLog("匯入的檔案為空", LOGGER);

            json.element("result""fileNull");

            print(json);

            return;

        }

        // 解析excel

        List<String[]> excelList = ExcelUtil.getExcelData(excel, 1);

 

        if (excelList.size() > 1000) {

            printDebugLog("匯入的Excel表格內容超過了最大1000", LOGGER);

            json.element("result""maxLength");

            print(json);

            return;

        }

 

        String lengthMsg = "", formatMsg = "", emptyMsg = "";

        int n = 2;

        // 格式校驗

        for (String[] data : excelList) {

            if (data.length > 17 || Tools.isEmpty(data)) {

                formatMsg += "第" + n + "行資料為空或者超出列數、";

            }

            if (data[0].length() > 20) {

                lengthMsg += "第" + n + "行題目編號、";

            }

            if (Tools.isEmpty(data[1])) {

                emptyMsg += "第" + n + "行題目標題、";

            else if (data[1].length() > 1000) {

                lengthMsg += "第" + n + "行題目標題、";

            }

            if (Tools.isEmpty(data[3])) {

                emptyMsg += "第" + n + "行有無題目附件、";

            else if (!"0".equals(data[3]) && !"1".equals(data[3])) {

                formatMsg += "第" + n + "行有無題目附件只能填0或1、";

            else if ("1".equals(data[3]) && Tools.isEmpty(data[4])) {

                formatMsg += "第" + n + "題目附件名必填、";

            else if ("0".equals(data[3]) && Tools.isNotEmpty(data[4])) {

                formatMsg += "第" + n + "題目附件名不必填、";

            }

            if (Tools.isNotEmpty(data[4]) && data[4].length() > 255) {

                lengthMsg += "第" + n + "行題目附件名、";

            }

            if (Tools.isNotEmpty(data[5]) && data[5].length() > 200) {

                lengthMsg += "第" + n + "行題目標籤、";

            }

            if (Tools.isEmpty(data[6])) {

                emptyMsg += "第" + n + "行所屬學科、";

            else if (!getCodeList(KeConstant.QUESTION_SUBJECT_TYPE_OWNID)

                                           .contains(data[6])) {

                formatMsg += "第" + n + "行所屬學科值不在範圍內、";

            }

            if (Tools.isEmpty(data[7])) {

                emptyMsg += "第" + n + "行題型類別、";

            else if (!getCodeList(KeConstant.QUESTION_TYPE_OWNID).contains(data[7])) {

                formatMsg += "第" + n + "行題型類別值不在範圍內、";

            }

            

             

            System.out.println(data[0] + "---" + data[1] + "---" + data[2]+

             "---" + data[3] + "---" + data[4] + "---"

                + data[5] + "---" + data[6] + "---" + data[7]);

            n++;

        }

        if (!"".equals(lengthMsg) || !"".equals(formatMsg) || !"".equals(emptyMsg)) {

            json.element("result""error");

            json.element("codeError", assembleErrorMsg(formatMsg,emptyMsg,lengthMsg));

            print(json);

            return;

        }

        // 存入資料庫操作======================================//

        // 新增列表

        boolean result = save(excelList);

        if (result) {

            json.element("result""success");

            print(json);

        else {

            json.element("result""fail");

            print(json);

        }

 

        // 請求結束log

        printEndLog("更新學生結束返回值:", json.toString(), LOGGER);

    }

 

    private Boolean save(List<String[]> excelList) throws Exception {

        List<KeQuestion> saveQuestionList = new ArrayList<KeQuestion>();

        Date now = new Date();

        for (String[] data : excelList) {

            KeQuestion saveQuestion = new KeQuestion();

            saveQuestion.setId(Tools.getUniqueId());

            saveQuestion.setTitle(data[1]);

            saveQuestion.setIndex(data[0]);

            saveQuestion.setContent(data[2]);

            saveQuestion.setHasAnnex(Integer.parseInt(data[3]) == 0?false:true);

            saveQuestion.setResourceUrl(data[4]);

            saveQuestion.setSpan(data[5]);

           ......

          

        }

        boolean result = true;

        result = questionService.insertQuestion(saveQuestionList);

        return result;

    }

    private String assembleErrorMsg(String formatMsg,String emptyMsg,String length) {

        String tabf = !"".equals(formatMsg)||!"".equals(emptyMsg)?"---""";

     String promptMsg="長度超過規定範圍。" + tabf : "";

        String tabs = !"".equals(emptyMsg) ? "---" "";

        promptMsg += !"".equals(formatMsg) ? formatMsg.substring(0, formatMsg.length()

         1) + "格式錯誤。" + tabs : "";

        promptMsg += !"".equals(emptyMsg) ? emptyMsg.substring(0, emptyMsg.length() 

        1) + "為空,無法匯入。" "";

        return promptMsg;

    }

注意:Excel的驗證根據自己的需求來判斷,驗證無誤的在通過物件儲存到資料庫中。Excel單元格通通為文字格式,不然有問題

遇到過的問題:當Excel最後一列為空時,比如一空有10列,但最後一列為空時拿到了ExcelList長度為9,,折騰了半天無果,就改為了通過第一行標題來獲取列長度,這樣就沒問題了。注意資料還是從第二行開始獲取。還有一個問題就是,當填的值為0等數字時,取到則為0.0,設定了Excel的單元格為文字格式還是沒用,需要設定為強文字格式(選擇單元格點導航欄資料中的分列,然後下一步,下一步,選擇文字,完成即可)。

然後還有就是一定要效驗好資料,不能漏了各種會出現的情況,不然儲存到資料庫出問題就大條了。

 

Excel的匯入

 

java程式碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

 /**

     * 匯出表格資訊為Excel

     

     * @throws Exception

     */

    public void excelExport() throws Exception {

 

        try {

            String[] titles = new String[] {"比賽名稱""報名人姓名"

                    "報名人手機號""身份證號""報名時間""分數"};

            String[] cols =

                new String[] {"partyName""userName""userPhone",

                     "userIdCard""creationTime","score"};

                     

            // 查詢比賽資訊

            ExaminationPartyInfo keywords = new ExaminationPartyInfo();

            keywords.setIsDeleted(Const.ISDELETED_FALSE).setType(Const.PARTYTYPE_BS);

            if (Tools.isNotEmpty(Jurisdiction.getMerchanismId())) {

                keywords.setMerchanismId(Jurisdiction.getMerchanismId());

            }

     List<ExaminationPartyInfo>partyList =examinationPartyInfoService.findList(keywords);

            // 查詢報名資訊

            ExaminationRegisterInfo condition = new ExaminationRegisterInfo();

            condition.setPartyIdArray(Tools.array2Long(StringUtil

                .listToString(partyList, "partyId")));

            List<ExaminationRegisterInfo> registerList =

                examinationRegisterInfoService.findList(condition);

 

            Map<String, Object> partyMap = Tools.list2Map(partyList, "partyId""name");

            Map<String, Object> userNameMap = new HashMap<String, Object>(16);

            Map<String, Object> userPhoneMap = new HashMap<String, Object>(16);

           Map<String, Object> userIdCardMap = new HashMap<String, Object>(16);

            if (registerList.size() > 0) {

                List<ExaminationUserInfo> userInfoList =

                   examinationUserInfoService.findByIdAsGroup(Tools.array2Long(StringUtil

                        .listToString(registerList, "userId")));

                if (userInfoList.size() > 0) {

                    userInfoList.stream().forEach(e -> {

                        userNameMap.put(String.valueOf(e.getUserId()), e.getName());

                        userPhoneMap.put(String.valueOf(e.getUserId()), e.getPhone());

                        userIdCardMap.put(String.valueOf(e.getUserId()), e.getIdCard());

                    });

                }

                registerList.stream().forEach(e -> {

                    e.put("partyName", partyMap.get(e.getPartyId()));

                    e.put("userName", userNameMap.get(e.getUserId()));

                    e.put("userPhone", userPhoneMap.get(e.getUserId()));

                    e.put("userIdCard", userIdCardMap.get(e.getUserId()));

                });

                ExaminationGradeInfo examinationGradeInfo =

                    getBean(ExaminationGradeInfo.class""true);

                examinationGradeInfo.setRegisterIdArray(Tools.array2Long(StringUtil.listToString(

                    registerList, "registerId")));

                examinationGradeInfo.setIsDeleted(Const.ISDELETED_FALSE);

                Page<ExaminationGradeInfo> examinationGradeInfoPage =

                    examinationGradeInfoService.findListInPageWithKeywords(

                        getParaToInt("pageNumber"), getParaToInt("pageSize"), examinationGradeInfo,

                        getPara("sortName"), getPara("sortOrder"));

 

                Map<String, Object> registerInfoMap = Tools.list2Map(registerList, "registerId");

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

                examinationGradeInfoPage.getList().forEach(

                    e -> {

                        Map<String, Object> map = new HashMap<String, Object>(16);

                        ExaminationRegisterInfo registerInfo =

                            (ExaminationRegisterInfo)registerInfoMap.get(e.getRegisterId());

                        if (registerInfo != null) {

                            map.put("userName", registerInfo.get("userName"));

                            map.put("userPhone", registerInfo.get("userPhone"));

                            map.put("userIdCard", registerInfo.get("userIdCard"));

                            map.put("partyName", registerInfo.get("partyName"));

                            map.put("creationTime", registerInfo.getCreationTime());

                        }

                        map.put("score", e.getScore());