springmvc文件上傳和下載,下載excel模板和導入excel數據(poi解析)


錄:

1、springmvc文件下載
2、springmvc文件上傳
3、下載excel模板的demo
4、導入excel數據的demo

 

1、springmvc文件下載    <--返回目錄

轉自:springmvc文件下載

1.1、

文件下載是web項目中常用的服務,在springmvc中常用ResponseEntity類來事項文件下載

1.2、ResponseEntity

ResponseEntity類實現響應頭、文件數據(以字節存儲)、狀態封裝在一起交給瀏覽器處理以實現瀏覽器的文件下載。簡單的說ResponseEntity可以折這HttpHeaders和HttpStatus,通過對HttpHeaders和HttpStatus的設置可以使瀏覽器執行下載操作。

1.3、實現文件下載

步驟

  1. 獲取到文件的存放的真實路徑
  2. 根據接收到的文件名和文件真實路徑創建文件實例(注意:這里不是創建一個文件,而是創建一個File型的實例)
  3. 設置響應頭Content-Disposition瀏覽器根據這個響應頭執行相應的操作和要下載的文件名
  4. 設置響應內容的MIME類型,以二進制流形式傳輸
  5. 返回ResponseEntity
@RequestMapping("/download")
public ResponseEntity<byte[]> download(@RequestParam("fileName") String fileName, HttpServletRequest req)
        throws IOException {

    // 獲取文件存放的真實路徑
    String realPath = req.getServletContext().getRealPath("/WEB-INF/file");
    //創建文件實例
    File file = new File(realPath, fileName);
    //修改文件名的編碼格式
    String downloadFileName = new String(fileName.getBytes("UTF-8"), "UTF-8");
    
    //設置httpHeaders,使瀏覽器響應下載
    HttpHeaders headers = new HttpHeaders();
    //告訴瀏覽器執行下載的操作,“attachment”告訴了瀏覽器進行下載,下載的文件 文件名為 downloadFileName
    headers.setContentDispositionFormData("attachment", downloadFileName); //設置響應方式為二進制,以二進制流傳輸
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
}

1.4、火狐瀏覽器測試

  從圖中我們可以看到,我們設置的Content-Disposition起效果,傳輸類型也為二進制。

 

2、springmvc文件上傳    <--返回目錄

轉自:springmvc文件上傳

2.1、

文件的上傳與下載基本上是web項目中會用到的技術,在web學習中我們用到的是 Apache fileupload這個組件來實現上傳,在springmvc中對它進行了封裝,讓我們使用起來比較方便,但是底層還是由Apache fileupload來實現的。springmvc中由MultipartFile接口來實現文件上傳。

2.2、MultipartFile接口

該接口用來實現springmvc中的文件上傳操作,它有兩個實現類:

 

 接口定義的方法:

 

2.3、實現文件上傳

導入jar包

  • commons-fileupload
  • commons-io

commons-io可以不用自己導入,maven會自動導入對應版本的jar

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

前端jsp頁面

  • input的type設置為file

  • form表單的method設為post,

  • form表單的enctype設置為multipart/form-data,以二進制的形式傳輸數據。

<%@ page language="java" contentType="text/html; charset=UTF-8"
      pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
  <form action="/ssm/file/imgUpload" enctype="multipart/form-data" method="post">
    <input type="file" name="file"><br><br>
    <input type="submit" value="上傳">
  </form>
</body>
</html>

Controller層接收

使用MultipartFile對象作為參數,接收前端發送過來的文件,將文件寫入本地文件中,就完成了上傳操作

@RequestMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest req)
        throws IllegalStateException, IOException {

    // 判斷文件是否為空,空則返回失敗頁面
    if (file.isEmpty()) {
        return "failed";
    }
    // 獲取文件存儲路徑(絕對路徑)
    String path = req.getServletContext().getRealPath("/WEB-INF/file");
    // 獲取原文件名
    String fileName = file.getOriginalFilename();
    // 創建文件實例
    File filePath = new File(path, fileName);
    // 如果文件目錄不存在,創建目錄
    if (!filePath.getParentFile().exists()) {
        filePath.getParentFile().mkdirs();
        System.out.println("創建目錄" + filePath);
    }
    // 寫入文件
    file.transferTo(filePath);
    return "success";
}  

springmvc.xml配置CommonsMultipartResolver

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--上傳文件的最大大小,單位為字節 --> 
    <property name="maxUploadSize" value="17367648787"></property>
     
    <!-- 上傳文件的編碼 -->
    <property name="defaultEncoding" value="UTF-8"></property>
</bean>

 

3、下載excel模板的demo    <--返回目錄

  excel模板設置單元格數據格式

 

   pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.oy</groupId>
    <artifactId>boot-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>boot-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.9</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
View Code

  PoiController

package com.oy.controller;

import java.io.InputStream;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class PoiController {

    @RequestMapping("/poi/download")
    public void download(HttpServletResponse response) throws Exception {
        InputStream is = getClass().getClassLoader().getResourceAsStream("static/exceltemplates/export1.xls");
        POIFSFileSystem fs = new POIFSFileSystem(is);
        HSSFWorkbook wb = new HSSFWorkbook(fs);
        ResponseUtil.export(response, wb, "下載模板excel.xls");
    }
}

  ResponseUtil

package com.oy.controller;

import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Workbook;

public class ResponseUtil {

    /**
     * 導出(或下載模板)
     *
     * @param response
     * @param wb       excel 工作簿
     * @param fileName 導出 excel 的文件名, 含后綴
     * @throws Exception
     */
    public static void export(HttpServletResponse response, Workbook wb, String fileName) throws Exception {
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "iso8859-1")); response.setContentType("application/ynd.ms-excel;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        wb.write(out);
        out.flush();
        out.close();
    }

}

 

4、導入excel數據的demo    <--返回目錄

  ExcelController

package com.guanxin.pm.controller.common;

import com.guanxin.base.annotation.Controller;
import com.guanxin.base.annotation.RequestParam;
import com.guanxin.base.annotation.Wrapper;
import com.guanxin.base.exception.ServiceException;
import com.guanxin.pm.facade.common.ExcelFacade;
import com.guanxin.web.utils.datatable.ctr.AjaxResponseWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

@Controller
@Component("/zxl_pm/common/excel.svc")
@Wrapper(AjaxResponseWrapper.class)
public class ExcelController {

    @Autowired
    private ExcelFacade excelFacade;

    /**
     * 模板數據(數據實體和數據字段)導入數據庫: 下載模板后, 手動填充數據后上傳; 后台讀取數據, 導入數據庫;
     *
     * @param file
     */
    public void importEntityAndFieldFromTemplate(@RequestParam("upFile") MultipartFile file,
                                                 @RequestParam("zxlPrdId") String zxlPrdId) throws Exception {
        Assert.hasText(zxlPrdId, "zxlPrdId不能為空");
        // 判斷文件是否為空, 空則直接返回
        if (file == null || file.isEmpty()) return;

        String fileName = file.getOriginalFilename();  //獲取上傳文件原名
        // 判斷文件是否為 excel 文件
        if (!(fileName.endsWith(".xls") || fileName.endsWith(".xlsx"))) {
            throw new ServiceException("請上傳 excel 格式文件");
        }
        excelFacade.importEntityAndFieldFromTemplate(file, zxlPrdId);
    }
    
}

 

  ExcelFacadeImpl

package com.guanxin.pm.facade.common.impl;

import com.guanxin.base.exception.ServiceException;
import com.guanxin.hibernate.annotations.Tx;
import com.guanxin.hibernate.support.HibernateSupport;
import com.guanxin.pm.dto.product.request.ZxlPrdRequestEntityDto;
import com.guanxin.pm.dto.product.request.ZxlPrdRequestFieldDto;import com.guanxin.pm.entity.product.request.ZxlPrdRequestEntity;import com.guanxin.pm.enums.product.request.*;
import com.guanxin.pm.facade.common.ExcelFacade;
import com.guanxin.pm.facade.product.request.*;
import com.guanxin.pm.utils.CommonUtil;
import com.guanxin.pm.utils.ExcelUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

/**
 * @Author oy
 * @Date 2020/11/10 17:20
 */
@Tx
@Component
public class ExcelFacadeImpl extends HibernateSupport implements ExcelFacade {

    @Autowired
    private EntityFacade entityFacade;
    @Autowired
    private FieldFacade fieldFacade;/**
     * 模板數據導入數據庫: 下載模板后, 手動填充數據后上傳; 后台讀取數據, 導入數據庫;
     *
     * @param file
     * @throws Exception
     */
    @Override
    public void importEntityAndFieldFromTemplate(MultipartFile file, String zxlPrdId) throws Exception {
        //InputStream is = new FileInputStream("e:\\entity_field_template_test.xls"); // 用於測試
        InputStream is = file.getInputStream(); // file ==> 輸入流
        POIFSFileSystem fs = new POIFSFileSystem(is);
        HSSFWorkbook wb = new HSSFWorkbook(fs); // 輸入流 ==> excel 工作簿

        HSSFSheet entitySheet = wb.getSheetAt(0); // 獲取第一個Sheet頁(數據實體)
        if (entitySheet == null) return;
        importEntity(entitySheet, zxlPrdId);

        HSSFSheet fieldSheet = wb.getSheetAt(1); // 獲取第二個Sheet頁(數據字段)
        if (fieldSheet == null) return;
        importField(fieldSheet, zxlPrdId);
    }/**
     * 導入數據實體
     *
     * @param hssfSheet
     * @throws Exception
     */
    private void importEntity(HSSFSheet hssfSheet, String zxlPrdId) throws Exception {
        // 遍歷行Row
        for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
            HSSFRow hssfRow = hssfSheet.getRow(rowNum);
            if (hssfRow == null) {
                continue;
            }

            ZxlPrdRequestEntityDto dto = new ZxlPrdRequestEntityDto();
            dto.setZxlPrdId(zxlPrdId);
            // 遍歷列Cell
            for (int cellNum = 0; cellNum <= hssfRow.getLastCellNum(); cellNum++) {
                HSSFCell hssfCell = hssfRow.getCell(cellNum);
                if (hssfCell == null) {
                    continue;
                }

                switch (cellNum) {
                    case 0: // 數據實體名
                        dto.setEntityName(ExcelUtils.getCellValue(hssfCell));
                        break;
                    case 1: // 數據實體編號
                        dto.setEntityNo(ExcelUtils.getCellValue(hssfCell));
                        break;
                    case 2: // 類型
                        String entityTypeVal = CommonUtil.getEnumNameByDesc(ExcelUtils.getCellValue(hssfCell), RequestEntityTypeEnum.class);
                        if (StringUtils.isNotBlank(entityTypeVal)) {
                            dto.setEntityType(RequestEntityTypeEnum.valueOf(entityTypeVal));
                        }
                        break;
                    case 3: // 修改模式
                        String editModelVal = CommonUtil.getEnumNameByDesc(ExcelUtils.getCellValue(hssfCell), RequestEntityEditModelEnum.class);
                        if (StringUtils.isNotBlank(editModelVal)) {
                            dto.setEditModel(RequestEntityEditModelEnum.valueOf(editModelVal));
                        }
                        break;
                    case 4: // 計算方式
                        String capacityTypeVal = CommonUtil.getEnumNameByDesc(ExcelUtils.getCellValue(hssfCell), RequestEntityCapacityTypeEnum.class);
                        if (StringUtils.isNotBlank(capacityTypeVal)) {
                            dto.setCapacityType(RequestEntityCapacityTypeEnum.valueOf(capacityTypeVal));
                        }
                        break;
                    case 5: // 數量
                        String capacityVal = ExcelUtils.getCellValue(hssfCell);
                        int index = capacityVal.lastIndexOf(".");
                        if (index > 0) {
                            capacityVal = capacityVal.substring(0, index);
                        }
                        dto.setEntityCapacity(Integer.valueOf(capacityVal));
                        break;
                    case 6: // 說明
                        dto.setNote(ExcelUtils.getCellValue(hssfCell));
                        break;
                    default:
                        break;
                }
            }

            Assert.hasText(dto.getZxlPrdId(), "產品id不能為空");
            Assert.hasText(dto.getEntityName(), "數據實體中文名不能為空");
            Assert.notNull(dto.getEntityType(), "數據實體類型不能為空");
            Assert.notNull(dto.getEditModel(), "數據修改模式不能為空");
            Assert.notNull(dto.getCapacityType(), "數據計算方式不能為空");
            entityFacade.saveOrUpdate(dto);
        }
        dao.flush();
    }

    /**
     * 導入數據字段
     *
     * @param hssfSheet
     * @throws Exception
     */
    private void importField(HSSFSheet hssfSheet, String zxlPrdId) throws Exception {
        // 遍歷行Row
        for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
            HSSFRow hssfRow = hssfSheet.getRow(rowNum);
            if (hssfRow == null) {
                continue;
            }

            ZxlPrdRequestFieldDto dto = new ZxlPrdRequestFieldDto();
            dto.setZxlPrdId(zxlPrdId);
            // 遍歷列Cell
            for (int cellNum = 0; cellNum <= hssfRow.getLastCellNum(); cellNum++) {
                HSSFCell hssfCell = hssfRow.getCell(cellNum);
                if (hssfCell == null) {
                    continue;
                }

                switch (cellNum) {
                    case 0: // 數據實體名稱
                        String entityNameVal = ExcelUtils.getCellValue(hssfCell);
                        ZxlPrdRequestEntity entity = entityFacade.findByName(zxlPrdId, entityNameVal);
                        if (entity == null) {
                            throw new ServiceException("導入數據字段時, 找不到數據實體為[" + entityNameVal + "]的記錄");
                        }
                        dto.setEntityId(entity.getEntityId());
                        break;
                    case 1: // 字段中文名稱
                        dto.setFieldName(ExcelUtils.getCellValue(hssfCell));
                        break;
                    case 2: // 字段類型
                        String fieldTypeVal = CommonUtil.getEnumNameByDesc(ExcelUtils.getCellValue(hssfCell), RequestFieldTypeEnum.class);
                        if (StringUtils.isNotBlank(fieldTypeVal)) {
                            dto.setFieldType(RequestFieldTypeEnum.valueOf(fieldTypeVal));
                        }
                        break;
                    case 3: // 輸入方式
                        String inputControlVal = CommonUtil.getEnumNameByDesc(ExcelUtils.getCellValue(hssfCell), RequestFieldInputControlEnum.class);
                        if (StringUtils.isNotBlank(inputControlVal)) {
                            dto.setInputControl(RequestFieldInputControlEnum.valueOf(inputControlVal));
                        }
                        break;
                    case 4: // 字段長度
                        String fieldLengthVal = ExcelUtils.getCellValue(hssfCell);
                        int index = fieldLengthVal.lastIndexOf(".");
                        if (index > 0) {
                            fieldLengthVal = fieldLengthVal.substring(0, index);
                        }
                        dto.setFieldLength(Integer.valueOf(fieldLengthVal));
                        break;
                    case 5: // 默認值
                        dto.setDefaultValue(ExcelUtils.getCellValue(hssfCell));
                        break;
                    case 6: // 字段描述
                        dto.setFieldDescribe(ExcelUtils.getCellValue(hssfCell));
                        break;
                    case 7: // 是否允許為空
                        String isNullVal = ExcelUtils.getCellValue(hssfCell);
                        Boolean isNull = ("是".equals(isNullVal) || StringUtils.isBlank(isNullVal)); // 默認允許為空
                        dto.setIsNull(isNull);
                        break;
                    case 8: // 是否為主鍵
                        String isKeyVal = ExcelUtils.getCellValue(hssfCell);
                        Boolean isKey = ("是".equals(isKeyVal) || StringUtils.isBlank(isKeyVal));
                        dto.setIsKey(isKey);
                        break;
                    default:
                        break;
                }
            }

            Assert.hasText(dto.getZxlPrdId(), "產品id不能為空");
            Assert.hasText(dto.getEntityId(), "數據實體id不能為空");
            Assert.hasText(dto.getFieldName(), "中文名稱不能為空");
            Assert.notNull(dto.getFieldType(), "字段類型不能為空");
            fieldFacade.saveOrUpdate(dto);
        }
        dao.flush();
    }

}

  ExcelUtils

package com.guanxin.pm.utils;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;

/**
 * @Author oy
 * @Date 2020/11/10 14:49
 */
public class ExcelUtils {

    /**
     * 導出(或下載模板)
     *
     * @param response
     * @param wb       excel 工作簿
     * @param fileName 導出 excel 的文件名, 含后綴
     * @throws Exception
     */
    public static void export(HttpServletResponse response, Workbook wb, String fileName) throws Exception {
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "iso8859-1"));
        response.setContentType("application/ynd.ms-excel;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        wb.write(out);
        out.flush();
        out.close();
    }

    /**
     * 獲取 excel 單元格的值
     *
     * @param hssfCell
     * @return
     */
    public static String getCellValue(HSSFCell hssfCell) {
        if (hssfCell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN) {
            return String.valueOf(hssfCell.getBooleanCellValue());
        } else if (hssfCell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
            return String.valueOf(hssfCell.getNumericCellValue());
        } else {
            return String.valueOf(hssfCell.getStringCellValue());
        }
    }
}

---


免責聲明!

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



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