1. 程式人生 > >SSM框架中excel表的的上傳和下載

SSM框架中excel表的的上傳和下載

一、頁面示例


二、Excel樣例(下面圖示不用管 該行刪除)


三、在Spring配置檔案中設定上傳檔案大小

<!--上傳檔案bean配置-->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!--設定上傳檔案大小-->
		<property name="maxInMemorySize" value="5000000"/>
	</bean>

四、編輯jsp(knowledge.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<%
    String importMsg = "";
    if (request.getSession().getAttribute("msg") != null) {
        importMsg = request.getSession().getAttribute("msg").toString();
    }
    request.getSession().setAttribute("msg", "");
%>
<head>
    <title>知識庫</title>
    <style>
        body{
            padding-top: 70px;
            padding-left: 190px;
        }
    </style>
    <script src="${pageContext.request.contextPath}/static/js/jquery-1.11.1.min.js"></script>
    <script type="text/javascript">
        function check() {
            var excel_file = $("#excel_file").val();
            if (excel_file == "" || excel_file.length == 0) {
                alert("請選擇檔案路徑!");
                return false;
            } else {
                return true;
            }
        }

        $(document).ready(function() {
            var msg = "";
            if ($("#importMsg").text() != null) {
                msg = $("#importMsg").text();
            }
            if (msg != "") {
                alert(msg);
            }
        });
    </script>
</head>
<body>
    <form action="knowledge/fileDown" method="get">
        <input type="submit" value="下載模板">
    </form>

    <div>
        <font color="blue">批量匯入客戶</font>
    </div>

    <form action="knowledge/uploadFile" method="post" enctype="multipart/form-data" onsubmit="return check();">
        <div style="margin: 30px;">
            <input id="excel_file" type="file" name="filename" accept="xlsx" size="80" />
            <input id="excel_button" type="submit" value="匯入Excel" />
        </div>
        <font id="importMsg" color="red"><%=importMsg%></font><input type="hidden" />
    </form>

</body>
</html>

五、編輯java檔案

5.1工具類程式碼(WDWUtil.java)(需要判斷Excel版本,不同版本字尾不同)

public class WDWUtil {
    // @描述:是否是2003的excel,返回true是2003
    public static boolean isExcel2003(String filePath)  {
        return filePath.matches("^.+\\.(?i)(xls)$");
    }

    //@描述:是否是2007的excel,返回true是2007
    public static boolean isExcel2007(String filePath)  {
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }
}

5.2工具類程式碼(ReadExcel.java

一般來說先將在客戶端使用者上傳的檔案拷貝一份至伺服器的本地磁碟中,然後再從這個拷貝檔案中進行讀取,這樣就避免了因客戶端的網路異常或其他狀況而在讀取時造成的資料流失或損壞的情況。

import com.wk.model.TKnowledge;
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;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by 鍇 on 2018/3/4.
 */
public class ReadExcel {
    //總行數
    private int totalRows = 0;
    //總條數
    private int totalCells = 0;
    //錯誤資訊接收器
    private String errorMsg;
    //構造方法
    public ReadExcel(){}
    //獲取總行數
    public int getTotalRows()  { return totalRows;}
    //獲取總列數
    public int getTotalCells() {  return totalCells;}
    //獲取錯誤資訊
    public String getErrorInfo() { return errorMsg; }

    /**
     * 驗證EXCEL檔案
     * @param filePath
     * @return
     */
    public boolean validateExcel(String filePath){
        if (filePath == null || !(WDWUtil.isExcel2003(filePath) || WDWUtil.isExcel2007(filePath))){
            errorMsg = "檔名不是excel格式";
            return false;
        }
        return true;
    }

    /**
     * 讀EXCEL檔案,獲取客戶資訊集合
     * @param fileName
     * @return
     */
    public List<TKnowledge> getExcelInfo(String fileName, MultipartFile Mfile){
        //把spring檔案上傳的MultipartFile轉換成CommonsMultipartFile型別
        CommonsMultipartFile cf= (CommonsMultipartFile)Mfile; //獲取本地儲存路徑
        File file = new File("C:\\fileupload");
        //建立一個目錄 (它的路徑名由當前 File 物件指定,包括任一必須的父路徑。)
        if (!file.exists())
            file.mkdirs();
        //新建一個檔案
//        File file1 = new File("C:\\fileupload" + new Date().getTime() + ".xlsx");
        File file1 = new File("C:\\fileupload" + File.separator + fileName);


        //將上傳的檔案寫入新建的檔案中
        try {
            cf.getFileItem().write(file1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //初始化客戶資訊的集合
        List<TKnowledge> knowledgeList=new ArrayList<TKnowledge>();
        //初始化輸入流
        InputStream is = null;
        try{
            //驗證檔名是否合格
            if(!validateExcel(fileName)){
                return null;
            }
            //根據檔名判斷檔案是2003版本還是2007版本
            boolean isExcel2003 = true;
            if(WDWUtil.isExcel2007(fileName)){
                isExcel2003 = false;
            }
            //根據新建的檔案例項化輸入流
            is = new FileInputStream(file1);
            //根據excel裡面的內容讀取客戶資訊
            knowledgeList = getExcelInfo(is, isExcel2003);
            is.close();
        }catch(Exception e){
            e.printStackTrace();
        } finally{
            if(is !=null)
            {
                try{
                    is.close();
                }catch(IOException e){
                    is = null;
                    e.printStackTrace();
                }
            }
        }
        return knowledgeList;
    }
    /**
     * 根據excel裡面的內容讀取客戶資訊
     * @param is 輸入流
     * @param isExcel2003 excel是2003還是2007版本
     * @return
     * @throws IOException
     */
    public  List<TKnowledge> getExcelInfo(InputStream is,boolean isExcel2003){
        List<TKnowledge> knowledgeList=null;
        try{
            /** 根據版本選擇建立Workbook的方式 */
            Workbook wb = null;
            //當excel是2003時
            if(isExcel2003){
                wb = new HSSFWorkbook(is);
            }
            else{//當excel是2007時
                wb = new XSSFWorkbook(is);
            }
            //讀取Excel裡面客戶的資訊
            knowledgeList=readExcelValue(wb);
        }
        catch (IOException e)  {
            e.printStackTrace();
        }
        return knowledgeList;
    }
    /**
     * 讀取Excel裡面客戶的資訊
     * @param wb
     * @return
     */
    private List<TKnowledge> readExcelValue(Workbook wb){
        //得到第一個shell
        Sheet sheet=wb.getSheetAt(0);

        //得到Excel的行數
        this.totalRows=sheet.getPhysicalNumberOfRows();

        //得到Excel的列數(前提是有行數)
        if(totalRows>=1 && sheet.getRow(0) != null){
            this.totalCells=sheet.getRow(0).getPhysicalNumberOfCells();
        }

        List<TKnowledge> customerList=new ArrayList<TKnowledge>();
        TKnowledge knowledge;
        //迴圈Excel行數,從第二行開始。標題不入庫
        for(int r=1;r<totalRows;r++){
            Row row = sheet.getRow(r);
            if (row == null) continue;
            knowledge = new TKnowledge();

            //迴圈Excel的列
            for(int c = 0; c <this.totalCells; c++){
                Cell cell = row.getCell(c);
                if (null != cell){
                    if(c==0){
                        knowledge.setQuestion1(cell.getStringCellValue());//問題
                        knowledge.setSolveNum(0);
                        knowledge.setUnsolveNum(0);
                        knowledge.setUseNum(0);
                    }else if(c==1){
                        knowledge.setAnswer(cell.getStringCellValue());//答案
                    }else if(c==2){
                        knowledge.setQuestion2(cell.getStringCellValue());//相似問題1
                    }else if(c==3){
                        knowledge.setQuestion3(cell.getStringCellValue());//相似問題2
                    }else if(c==4){
                        knowledge.setQuestion4(cell.getStringCellValue());//相似問題3
                    }else if(c==5){
                        knowledge.setQuestion5(cell.getStringCellValue());//相似問題4
                    }else if(c==6){
                        knowledge.setQuestion6(cell.getStringCellValue());//相似問題5
                    }
                }
            }
            //新增知識
            customerList.add(knowledge);
        }
        return customerList;
    }


}

5.3服務層程式碼(KnowledgeService.java)

@Resource
    private TKnowledgeMapper knowledgeMapper;
@Override
    public boolean batchImort(String name, MultipartFile file) {
        boolean b = false;
        //建立處理EXCEL
        ReadExcel readExcel=new ReadExcel();
        //解析excel,獲取客戶資訊集合。
        List<TKnowledge> knowledgeList = readExcel.getExcelInfo(name ,file);

        if(knowledgeList != null){
            b = true;
        }
        //迭代新增客戶資訊(注:實際上這裡也可以直接將customerList集合作為引數,在Mybatis的相應對映檔案中使用foreach標籤進行批量新增。)
        for(TKnowledge knowledge:knowledgeList){
            knowledgeMapper.insert(knowledge);
        }
        return b;
    }

    @Override
    public int insert(TKnowledge record) {
        return knowledgeMapper.insert(record);//插入一條資料
    }

5.4控制器程式碼(KnowledgeController.java)

@Controller
@RequestMapping("/web/knowledge")
public class KnowledgeController {
    @Resource
    private KnowledgeService knowledgeService;

    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    public String uploadFile(@RequestParam(value = "filename") MultipartFile file,
                             HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("開始上傳檔案");
        //判斷檔案是否為空
        if (file == null) return null;
        //獲取檔名
        String name = file.getOriginalFilename();
        //進一步判斷檔案是否為空(即判斷其大小是否為0或其名稱是否為null)
        long size = file.getSize();
        if (name == null || ("").equals(name) && size == 0) return null;

        //批量匯入。引數:檔名,檔案。
        boolean b = knowledgeService.batchImort(name, file);
        if (b) {
            String Msg = "批量匯入EXCEL成功!";
            request.getSession().setAttribute("msg", Msg);
        } else {
            String Msg = "批量匯入EXCEL失敗!";
            request.getSession().setAttribute("msg", Msg);
        }
        return "web/knowledge";
    }

    @RequestMapping(value = "/fileDown", method = RequestMethod.GET)
    public void down(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //模擬檔案,myfile.txt為需要下載的檔案
        String fileName = request.getSession().getServletContext().getRealPath("static/file/知識庫匯入模板.xls");
        System.out.println(fileName);
        //獲取輸入流
        InputStream bis = new BufferedInputStream(new FileInputStream(new File(fileName)));
        //假如以中文名下載的話
        String filename = "知識庫匯入模板.xls";
        //轉碼,免得檔名中文亂碼
        filename = URLEncoder.encode(filename,"UTF-8");
        //設定檔案下載頭
        response.addHeader("Content-Disposition", "attachment;filename=" + filename);
        //1.設定檔案ContentType型別,這樣設定,會自動判斷下載檔案型別
        response.setContentType("multipart/form-data");
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        int len = 0;
        while((len = bis.read()) != -1){
            out.write(len);
            out.flush();
        }
        out.close();
    }
}

六、最後附上專案結構


此部落格忽略模型層程式碼,工具類和模型層可根據需求更改