木心

毕竟几人真得鹿,不知终日梦为鱼

导航

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());
        }
    }
}

---

posted on 2020-11-12 10:33  wenbin_ouyang  阅读(1829)  评论(1编辑  收藏  举报