1、springmvc文件下載
2、springmvc文件上傳
3、下載excel模板的demo
4、導入excel數據的demo
1、springmvc文件下載 <--返回目錄
1.1、
文件下載是web項目中常用的服務,在springmvc中常用ResponseEntity類來事項文件下載
1.2、ResponseEntity
ResponseEntity類實現響應頭、文件數據(以字節存儲)、狀態封裝在一起交給瀏覽器處理以實現瀏覽器的文件下載。簡單的說ResponseEntity可以折這HttpHeaders和HttpStatus,通過對HttpHeaders和HttpStatus的設置可以使瀏覽器執行下載操作。
1.3、實現文件下載
步驟:
- 獲取到文件的存放的真實路徑
- 根據接收到的文件名和文件真實路徑創建文件實例(注意:這里不是創建一個文件,而是創建一個File型的實例)
- 設置響應頭Content-Disposition瀏覽器根據這個響應頭執行相應的操作和要下載的文件名
- 設置響應內容的MIME類型,以二進制流形式傳輸
- 返回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文件上傳 <--返回目錄
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>
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()); } } }
---