Jsp檔案下載 (Excel檔案處理部分在後段)

要用Jsp下載,必須先要安裝Apache Commons FileUpload 和 Apache Commons IO

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
  
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>

我的版本為這兩個

先建立一個簡單的html頁面

<html>
<head>
<title>File Upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=big5" />
</head>
<body>
<p><font><b>檔案上傳</b></font></p>

<form name="upload" enctype="multipart/form-data" method="post" action="fileupload.jsp"> 
<p>上傳檔案: <input type="file" name="file" size="20" maxlength="20" /> </p>
<p>檔案說明: <input type="text" name="filedesc" size="30" maxlength="50" /> </p>
<p> <input type="submit"value="上傳" /> <input type="reset" value="清除" /> </p>
</form>

</body>
</html>

jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page import="java.io.File"%>
<%@ page import="java.util.Iterator"%>
<%@ page import="java.util.List"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page import="org.apache.commons.io.FilenameUtils"%>
<%
    String saveDirectory = application.getRealPath("/upload");
    
    // Check that we have a file upload request
    boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    out.println("isMultipart="+isMultipart+"<br>");
    
    // Create a factory for disk-based file items
    FileItemFactory factory = new DiskFileItemFactory();
 
    // Create a new file upload handler
    ServletFileUpload upload = new ServletFileUpload(factory);

    //Create a progress listener
    ProgressListener progressListener = new ProgressListener(){
       private long megaBytes = -1;
       public void update(long pBytesRead, long pContentLength, int pItems) {
           long mBytes = pBytesRead / 1000000;
           if (megaBytes == mBytes) {
               return;
           }
           megaBytes = mBytes;
           System.out.println("We are currently reading item " + pItems);
           if (pContentLength == -1) {
               System.out.println("So far, " + pBytesRead + " bytes have been read.");
           } else {
               System.out.println("So far, " + pBytesRead + " of " + pContentLength
                                  + " bytes have been read.");
           }
       }
    };
    upload.setProgressListener(progressListener);
    
    // Parse the request
    List /* FileItem */ items = upload.parseRequest(request);
    
    // Process the uploaded items
    Iterator iter = items.iterator(); 
    while (iter.hasNext()) {
        FileItem item = (FileItem) iter.next();

        if (item.isFormField()) {
            // Process a regular form field
            //processFormField(item);
            String name = item.getFieldName();
            String value = item.getString();
            value = new String(value.getBytes("UTF-8"), "ISO-8859-1");
            out.println(name + "=" + value+"<br>");
        } else {
            // Process a file upload
            //processUploadedFile(item);
            String fieldName = item.getFieldName();
            String fileName = item.getName();
            String contentType = item.getContentType();
            boolean isInMemory = item.isInMemory();
            long sizeInBytes = item.getSize();
            out.println("fieldName="+fieldName+"<br>");
            out.println("fileName="+fileName+"<br>");
            out.println("contentType="+contentType+"<br>");
            out.println("isInMemory="+isInMemory+"<br>");
            out.println("sizeInBytes="+sizeInBytes+"<br>");
            if (fileName != null && !"".equals(fileName)) {
                fileName= FilenameUtils.getName(fileName);
                out.println("fileName saved="+fileName+"<br>");
                File uploadedFile = new File(saveDirectory, fileName);
                item.write(uploadedFile);
            }            
        }
    }                
%>

參考資料
https://www.andowson.com/posts/list/197.page



個人本身在Spring上的寫法
.xml

<bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" /> <!-- dataSoruce 自行設定-->
        <property name="packagesToScan" value="com.entities" />
<property name="hibernateProperties">
<props>
<!-- OracleConnect-->
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> 
<!-- MySqlConnect 
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>-->
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
<prop key="format_sql">true</prop>
<prop key="use_sql_comments">true</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">true</prop> -->
</props>
</property>
</bean>

一個簡易的jsp頁面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<title>Upload</title>
</head>
<body>
<div>
<p>請選擇檔案:</p>
    <form id="uploadForm">
            <input name="file" id="file" type="file">
        </form>
        <p>
        <button id="button">上傳</button>
        </p>
    </div>
</body>
<script>
$("#button").on("click",function(){
var file = $("#file").val();

        //檢測是否有選擇檔案
        if (file == "" || file == null) {
            alert("請選擇檔案");
            return;
        } 

        //檢測副檔名是否為.pdf
        var subname = file.substring(file.lastIndexOf('.'));
        if (subname == ".xls" || subname == ".xlsx") {
var str = "";
        }else {
            alert("檔案不是Execl格式,請重新上傳");
            return;
        }
        
        var formData = new FormData($("#uploadForm")[0]);
        
        $.ajax({
            url: 'uploadFile',
            contentType: false,
            async: true,
            type: "POST",
            cache: false,
            processData: false,
            data: formData,
            error: function (jqXHR, textStatus, errorThrown) {
                alert("系統可能哪裡出了問題,上傳失敗,請重新開啟畫面再試");
            },
            success: function (response) {
                alert(response.message);
            }
        })
})
</script>
</html>

entities.java 用於連接DB,請自行建立自己的table等

controller用於控制網頁回傳值以及處理

package com.controllers;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.entities.Score;
import com.services.UploadServices;

@Controller
@RequestMapping(value="upload")
public class UploadController {

private static final Logger log = Logger.getLogger(UploadController.class);
@Autowired
UploadServices uploadServices;
@RequestMapping(value = "/page", method = RequestMethod.GET)
public ModelAndView getPage() {
ModelAndView view = new ModelAndView("upload");
log.debug("開啟Upload頁面");
return view;
}
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public @ResponseBody Map<String,Object> uploadFile(HttpServletRequest request) 
throws ServletException, IOException{
Map<String,Object> map = new HashMap<String,Object>();
String filePath = "";
List<Score> scoreList = null;
int count = 0;
try {
filePath = uploadServices.saveFile(request);
count++;
} catch (Exception e) {
log.debug("檔案上傳失敗,錯誤為  : " + e.toString());
map.put("message", "上傳檔案過程發生錯誤,請重新再試或聯絡資訊部人員");
return map;
}
if (count == 1) {
try {
scoreList = uploadServices.getScoreList(filePath);
count++;
} catch (Exception e) {
log.debug("取得陣列資料失敗,錯誤為  : " + e.toString());
map.put("message", "上傳檔案成功,但解析過程出問題,請重新再試或聯絡資訊部人員");
return map;
}
}
if (count == 2) {
try {
uploadServices.saveAndUpdate(scoreList);
map.put("message", "執行成功");
} catch (Exception e) {
log.debug("上傳資料庫失敗,錯誤為  : " + e.toString());
map.put("message", "上傳檔案成功,但資料庫傳輸過程出問題,請重新再試或聯絡資訊部人員");
return map;
}
}
return map;
}
}

services //處理功能

package com.servicesImpl;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.controllers.UploadController;
import com.dao.UploadDao;
import com.entities.Score;
import com.services.UploadServices;

@Service
public class UploadServicesImpl implements UploadServices{

private static final Logger log = Logger.getLogger(UploadController.class);
private static final int MEMORY_THRESHOLD   = 1024 * 1024 * 3 ;
private static final int MAX_FILE_SIZE      = 1024 * 1024 * 40;
private static final int MAX_REQUEST_SIZE   = 1024 * 1024 * 50;
@Autowired
UploadDao uploadDao;

@Override
public String saveFile(HttpServletRequest request)
throws ServletException, IOException {

log.debug("開始執行saveFile方法上傳檔案");

// 建立一個以disk-base的檔案物件
DiskFileItemFactory factory = new DiskFileItemFactory();
// 初始化內容
        // 傳送所用的buffer空間
factory.setSizeThreshold(MEMORY_THRESHOLD);
// 設定檔案暫存位置
// System.getProperty("java.io.tmpdir")是獲取操作系統暫存的臨時目錄
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

// 建立一個檔案上傳的物件
ServletFileUpload upload = new ServletFileUpload(factory);
// 最大檔案大小
upload.setFileSizeMax(MAX_FILE_SIZE);

// 最大請求值(包含檔案大小和表單數據)
upload.setSizeMax(MAX_REQUEST_SIZE);
// UTF-8編碼
upload.setHeaderEncoding("UTF-8");
//儲存路徑
String uploadPath = "C:\\Users\\Marya\\Desktop\\test";
// 如果目錄不在就建立
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
String filePath = "";
try {
// 取得上傳物件陣列(上傳檔案個數)
List<FileItem> formItems = upload.parseRequest(request);
// 判斷陣列是否為空和陣列大小
if (formItems != null && formItems.size() > 0) {
for (FileItem item : formItems) {
// 是否為純文字檔
if (!item.isFormField()) {
// 取得檔名
String fileName = item.getName();
// 建立完整檔案路徑 ,File.separator='/'
filePath = uploadPath + File.separator + fileName;
// 建立檔案
File storeFile = new File(filePath);
// 輸出檔案內容
item.write(storeFile);
log.debug("成功上傳檔案,檔案名為 : " + fileName);
}
}
log.debug("上傳檔案完畢");
log.debug("回傳路徑為 : " + filePath);
return filePath;
}
return null;
} catch (Exception e) {
log.debug("上傳檔案發生錯誤,錯誤為 : " + e.toString());
filePath = "";
return null;
}
}

@SuppressWarnings("resource")
@Override
public List<Score> getScoreList(String filePath) 
throws FileNotFoundException, IOException {
log.debug("開始執行getScoreList方法解析資料");
List<Score> scoreList = new ArrayList<Score>();
try {
//建立資料流
InputStream is = new FileInputStream(filePath);
//建立工作本
Workbook workbook = null;
//判斷資料表格式,xls使用HSSF、xlsx使用XSSF
String extString = filePath.substring(filePath.lastIndexOf(".")+1);
if("xls".equals(extString)){
workbook = new HSSFWorkbook(is);
}else if("xlsx".equals(extString)){
workbook = new XSSFWorkbook(is);
}
//取得第一個工作表
XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(0);
//取得行數
int rowNum=sheet.getLastRowNum();
log.debug("資料筆數 : " + rowNum);
log.debug("開始寫入資料");
for(int i=1;i<=rowNum;i++){
//取得每列資料
XSSFRow row = sheet.getRow(i);
String number = row.getCell(0).toString();
String name = row.getCell(1).toString();
String chinese = row.getCell(2).toString();
String math = row.getCell(3).toString();
String english = row.getCell(4).toString();
//處理資料
int number_int = (int)Float.parseFloat(number);
int chinese_int = (int)Float.parseFloat(chinese);
int math_int = (int)Float.parseFloat(math);
int english_int = (int)Float.parseFloat(english);
//建立Score物件
Score score = new Score();
score.setNumber(number_int);
score.setName(name);
score.setChinese(chinese_int);
score.setMath(math_int);
score.setEnglish(english_int);
scoreList.add(score);
}
workbook.close();
log.debug("成功取得資料陣列");
return scoreList;
} catch (Exception e) {
log.debug("讀取資料表發生錯誤,錯誤為 : " + e.toString());
return null;
}
}
@Override
public void saveAndUpdate(List<Score> scoreList) 
throws ServletException, IOException {
try {
log.debug("開始執行saveAndUpdate方法上傳資料庫");
uploadDao.saveOrUpdate(scoreList);
log.debug("成功上傳資料庫");
} catch (Exception e) {
log.debug("上傳資料庫發生錯誤,錯誤為 : " + e.toString());
}

}
}

Dao //建立連線

package com.daoImpl;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.dao.UploadDao;
import com.entities.Score;

@Repository
@Transactional
public class UploadDaoImpl implements UploadDao{
private static final Logger log = Logger.getLogger(UploadDaoImpl.class);
@Autowired
SessionFactory session;
public void saveOrUpdate(List<Score> scoreList){
try {
for (Score score : scoreList){
session.getCurrentSession().saveOrUpdate(score);
}
} catch (HibernateException e) {
log.debug("上傳資料庫發生錯誤,錯誤為 : " + e.toString());
}
}
}
參考資料
https://blog.yslifes.com/archives/526

POI 對 Excel 的處理脈絡是這樣,先有一個 Workbook,把他看成是一個 Excel,下一層是頁籤 Sheet,再下一層是橫的 Row,最後就是儲存格 Cell。

參考資料
https://noter.tw/6723/java-%E5%AF%AB%E5%85%A5-excel-%E6%96%87%E4%BB%B6xls-xlsx-%E4%BD%BF%E7%94%A8-apache-poi/










留言

這個網誌中的熱門文章

無法載入檔案或組件 'System.IO.Compression' 或其相依性的其中之一。

MongoDB 入門

javascript 更改屬性及創建標籤