代码拉取完成,页面将自动刷新
package com.wmx.www.controller;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Spring Boot 文件下载方式汇总
*
* @author wangMaoXiong
* Created by Administrator on 2019/3/17 0017.
*/
@Controller
@SuppressWarnings("Duplicates")
public class DownloadFileController {
private static final Logger log = LoggerFactory.getLogger(DownloadFileController.class);
private static final Map<String, String> imageMap = new HashMap<>();
private static final Map<String, String> videoMap = new HashMap<>();
static {
imageMap.put("1", "static/images/气质美女.jpg");
imageMap.put("2", "static/images/凶猛老虎.jpg");
videoMap.put("3", "static/videos/演戏连跑步都需要假跑吗.mp4");
videoMap.put("4", "static/videos/美女路边直播,路过家长翻了一个白眼.mp4");
}
/**
* 单文件下载
* 1、使用原生 InputStream 流读写文件。
* 2、支持任意格式的文件。
* http://localhost:8080/fileServer/singleDownload1?fileId=1
* http://localhost:8080/fileServer/singleDownload1?fileId=2
*
* @param response
* @param fileId :被下载文件ID
* @throws IOException
*/
@RequestMapping(value = {"/singleDownload1"}, method = {RequestMethod.GET})
public void singleDownload1(HttpServletResponse response, String fileId) throws Exception {
log.debug("文件下载开始:{}", fileId);
// 构建文件输入流(推荐使用:org.apache.commons.io.FileUtils.readFileToByteArray)
File downloadFile = this.getFile(fileId);
// 获取文件的媒体类型
String contentType = Files.probeContentType(downloadFile.toPath());
if (contentType == null) {
// 获取失败时使用通用的文件类型(application/octet-stream)
contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
}
// 原生IO流读取方式
try (InputStream inputStream = new FileInputStream(downloadFile);
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
String filename = downloadFile.getName();
// 设置返回类型,如果是返回普通文本信息,则也可以使用:response.setContentType("text/html;charset=utf-8");
response.setContentType(contentType);
// 设置文件内容大小
response.setContentLengthLong(Files.size(downloadFile.toPath()));
// 设置返回的头信息,对文件名称进行编码,否则中文容易乱码。
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
int length;
byte[] bytes = new byte[1024];
while ((length = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, length);
}
outputStream.flush();
outputStream.close();
log.info("文件下载完成:{}", fileId);
}
}
/**
* 单文件下载
* 1、使用第三方API快速读写,如 Apache 的工具类 FileUtils、IOUtils:
* * org.apache.commons.io.FileUtils.readFileToByteArray 读取文件字节内容.
* * org.apache.commons.io.IOUtils#write(byte[], java.io.OutputStream)
* * org.apache.commons.io.IOUtils#copy(java.io.InputStream, java.io.OutputStream)
* 2、支持任意格式的文件。
* http://localhost:8080/fileServer/singleDownload2?fileId=2
*
* @param response
* @param fileId :被下载文件ID
* @return
*/
@RequestMapping(value = {"/singleDownload2"}, method = {RequestMethod.GET})
public void singleDownload2(HttpServletResponse response, String fileId) throws Exception {
try (OutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {
log.debug("文件下载开始:{}", fileId);
File downloadFile = this.getFile(fileId);
// 获取文件的媒体类型
String contentType = Files.probeContentType(downloadFile.toPath());
if (contentType == null) {
// 获取失败时使用通用的文件类型(application/octet-stream)
contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
}
String filename = downloadFile.getName();
// 设置返回类型,如果是返回普通文本信息,则也可以使用:response.setContentType("text/html;charset=utf-8");
response.setContentType(contentType);
// 设置文件内容大小
response.setContentLengthLong(Files.size(downloadFile.toPath()));
// 设置返回的头信息,对文件名称进行编码,否则中文容易乱码。
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
// 构建文件输入流(推荐使用org.apache.commons.io.FileUtils.readFileToByteArray)
byte[] byteArray = FileUtils.readFileToByteArray(downloadFile);
// org.apache.commons.io.IOUtils.write(byteArray, response.getOutputStream());
// 写入到输出流返回给客户端
outputStream.write(byteArray);
}
log.info("文件下载完成:{}", fileId);
}
/**
* 单文件下载
* 1、使用 Jdk8 的 nio 的原生 API:Files、Paths API 读写文件
* 2、支持任意格式的文件。
* http://localhost:8080/fileServer/singleDownload3?fileId=2
*
* @param response
* @param fileId :被下载文件ID
* @return
*/
@RequestMapping(value = {"/singleDownload3"}, method = {RequestMethod.GET})
public void singleDownload3(HttpServletResponse response, String fileId) {
OutputStream outputStream = null;
try {
outputStream = response.getOutputStream();
// 获取被下载文件
File downloadFile = this.getFile(fileId);
Path downloadFilePath = downloadFile.toPath();
String filename = downloadFile.getName();
// 获取文件的媒体类型
String contentType = Files.probeContentType(downloadFilePath);
if (contentType == null) {
// 获取失败时使用通用的文件类型(application/octet-stream)
contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
}
response.setContentType(contentType);
// 文件大小
response.setContentLengthLong(Files.size(downloadFilePath));
// 设置返回的头信息(Content-Disposition),对文件名称进行编码,否则中文容易乱码。
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
// 响应数据给客户端
Files.copy(downloadFilePath, outputStream);
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e1) {
log.error(ExceptionUtils.getStackTrace(e1));
}
}
}
}
/**
* http://localhost:8080/fileServer/singleDownload4?fileId=2
* <p>
* 第三方 hutool 的工具类 FileUtil、IoUtil:
* cn.hutool.core.io.IoUtil#copy(java.io.InputStream, java.io.OutputStream)
* cn.hutool.core.io.FileUtil.writeToStream(File file, OutputStream out)
*
* @param response
*/
@RequestMapping(value = {"/singleDownload4"}, method = {RequestMethod.GET})
public void singleDownload4(HttpServletResponse response) {
OutputStream outputStream = null;
try {
String filePath = "static/videos/演戏连跑步都需要假跑吗.mp4";
String filename = FileUtil.getName(filePath);
outputStream = response.getOutputStream();
// 获取文件的媒体类型(application/octet-stream)
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
// 设置返回的头信息(Content-Disposition),对文件名称进行编码,否则中文容易乱码。
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
// 方式1
// InputStream inputStream = DownloadFileController.class.getClassLoader().getResourceAsStream(filePath);
// cn.hutool.core.io.IoUtil.copy(inputStream, outputStream);
// 方式2
URL url = DownloadFileController.class.getClassLoader().getResource(filePath);
File file = FileUtil.file(url);
FileUtil.writeToStream(file, outputStream);
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e1) {
log.error(ExceptionUtils.getStackTrace(e1));
}
}
}
}
/**
* Spring的Resource抽象提供了对不同来源资源的统一访问方式,非常适合文件下载场景。
* http://localhost:8080/fileServer/responseEntity1/1
*
* @param fileId :类路径下的文件ID
* @return
*/
@GetMapping("/responseEntity1/{fileId:.+}")
public ResponseEntity<Resource> responseEntity1(@PathVariable String fileId) {
try {
// 类路径下的文件,资源文件,打成包也能访问.
URL url = DownloadFileController.class.getClassLoader().getResource(imageMap.get(fileId));
Resource resource = new UrlResource(url);
// 电脑上/服务器上的独立文件
// Path filePath = Paths.get("F:\\Music\\1987我不知会遇见你 - 李宇春.mp3");
// Resource resource = new UrlResource(filePath.toUri());
// 检查资源是否存在
if (resource.exists()) {
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
} else {
return ResponseEntity.notFound().build();
}
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
return ResponseEntity.badRequest().build();
}
}
/**
* SpringBoot中,ResponseEntity类型可以精确控制HTTP响应,为文件下载提供完善的HTTP头信息。
* http://localhost:8080/fileServer/responseEntity2/1
*
* @param fileId
* @return
*/
@GetMapping("/responseEntity2/{fileId:.+}")
public ResponseEntity<byte[]> responseEntity2(@PathVariable String fileId) {
try {
File downloadFile = this.getFile(fileId);
String fileName = downloadFile.getName();
byte[] data = Files.readAllBytes(downloadFile.toPath());
// String fileAddr = "E:\\IDEA_Projects\\material\\doc\\IDEA多实例启动服务.pdf";
// Path path = Paths.get(fileAddr);
// String fileName = path.getFileName().toString();
// byte[] data = Files.readAllBytes(path);
HttpHeaders headers = new HttpHeaders();
headers.setContentDisposition(ContentDisposition.builder("attachment").filename(fileName, StandardCharsets.UTF_8).build());
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// headers.setContentType(MediaType.APPLICATION_PDF);// pdf不这样明确指定,直接指定为上面的流类型也是可以的.
headers.setContentLength(data.length);
return new ResponseEntity<>(data, headers, HttpStatus.OK);
} catch (IOException e) {
log.error(ExceptionUtils.getStackTrace(e));
return ResponseEntity.badRequest().build();
}
}
/**
* http://localhost:8080/fileServer/zipDownload1?fileId=2
* 多个文件压缩成一个文件后下载.
* 1、本方法使用原生API进行压缩。
* 2、也可以使用第三方的解压库:
* * Apache Commons Compress 文件解压缩库:https://wangmaoxiong.blog.csdn.net/article/details/103943688#文件压缩并提供网络下载
*
* @param fileId :被下载的文件ID,多个时使用逗号分割,如 1,2,3,4
* @param response
* @throws Exception
*/
@GetMapping("/zipDownload1")
public void zipDownload1(String fileId, HttpServletResponse response) throws Exception {
// 要下载的文件列表
List<Path> listPath = this.listPath(fileId);
String zipFileName = listPath.get(0).getFileName() + "等" + listPath.size() + "个.zip";
// 设置发送到客户端的响应的内容类型
response.setContentType("application/zip");
// 设置返回的头信息(Content-Disposition),对文件名称进行编码,否则中文容易乱码。
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(zipFileName, "UTF-8"));
// 压缩多个文件到zip文件中,并且响应给客户端
try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream())) {
for (Path path : listPath) {
try (InputStream inputStream = Files.newInputStream(path)) {
zipOutputStream.putNextEntry(new ZipEntry(path.getFileName().toString()));
StreamUtils.copy(inputStream, zipOutputStream);
zipOutputStream.flush();
}
}
}
}
/**
* http://localhost:8080/fileServer/zipDownload2?fileId=1,2,3,4
* 多个文件压缩成一个文件后下载.
* 1、本方法使用第三方的 hutool ZipUtil 压缩。
* 2、也可以使用其他第三方的解压库:
* * Apache Commons Compress 文件解压缩库:https://wangmaoxiong.blog.csdn.net/article/details/103943688#文件压缩并提供网络下载
*
* @param fileId :被下载的文件ID,多个时使用逗号分割,如 1,2,3,4
* @param response
* @throws Exception
*/
@GetMapping("/zipDownload2")
public void zipDownload2(String fileId, HttpServletResponse response) throws Exception {
// 要下载的文件列表
Map<String, InputStream> inputStreamMap = listInputStream(fileId);
// 被压缩文件的输入流
List<InputStream> inputStreams = new ArrayList<>();
List<String> paths = new ArrayList<>();
// 压缩包中文件对应的名字
for (Map.Entry<String, InputStream> entry : inputStreamMap.entrySet()) {
paths.add(new File(entry.getKey()).getName());
inputStreams.add(entry.getValue());
}
String zipFileName = paths.get(0) + "等" + paths.size() + "个.zip";
// 设置发送到客户端的响应的内容类型
response.setContentType("application/zip");
// 设置返回的头信息(Content-Disposition),对文件名称进行编码,否则中文容易乱码。
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(zipFileName, "UTF-8"));
/**
* zip(OutputStream out, String[] paths, InputStream[] ins):将文件流压缩到目标流中
* @param out 目标流,压缩完成自动关闭,web 环境时,使用 response.getOutputStream() 返回 ServletOutputStream 输出即可进行网络下载.
* @param paths 流数据在压缩文件中的路径或文件名,可以自己随意定义,会按顺序给后面的 ins 进行命名.
* @param ins 要压缩的源,添加完成后自动关闭流
*/
OutputStream destOutputStream = response.getOutputStream();
ZipUtil.zip(destOutputStream, paths.toArray(new String[0]), inputStreams.toArray(new InputStream[0]));
}
/**
* http://localhost:8080/fileServer/zipDownload3?fileId=1,2,3,4
* 多个文件压缩成一个文件后下载.
* 1、本方法使用第三方的 Apache Commons Compress 文件解压缩库
*
* @param fileId :被下载的文件ID,多个时使用逗号分割,如 1,2,3,4
* @param response
* @throws Exception
*/
@GetMapping("/zipDownload3")
public void zipDownload3(@RequestParam String fileId, HttpServletResponse response) {
String zipFileName = "内部资料,请勿外传" + ".zip";
Map<String, InputStream> inputStreamMap = listInputStream(fileId);
// 通过 OutputStream 创建 zip 压缩流。如果是压缩到本地,也可以直接使用 ZipArchiveOutputStream(final File file)
try (ServletOutputStream servletOutputStream = response.getOutputStream();
ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(servletOutputStream)) {
// 设置文件响应头信息
response.setContentType("content-type:octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFileName, "utf-8"));
// setUseZip64(final Zip64Mode mode):是否使用 Zip64 扩展。
// Zip64Mode 枚举有 3 个值:
// * Always:对所有条目使用 Zip64 扩展
// * Never:不对任何条目使用Zip64扩展
// * AsNeeded:对需要的所有条目使用Zip64扩展
zipArchiveOutputStream.setUseZip64(Zip64Mode.AsNeeded);
for (Map.Entry<String, InputStream> inputStreamEntry : inputStreamMap.entrySet()) {
String fileName = FileUtil.getName(inputStreamEntry.getKey());
InputStream inputStream = inputStreamEntry.getValue();
// 使用 ByteArrayOutputStream 读取文件字节
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int readLength;
while ((readLength = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, readLength);
}
if (byteArrayOutputStream != null) {
byteArrayOutputStream.flush();
}
// 整个文件字节数据
byte[] fileBytes = byteArrayOutputStream.toByteArray();
// 用指定的名称创建一个新的 zip 条目(zip压缩实体),然后设置到 zip 压缩输出流中进行写入.
ArchiveEntry entry = new ZipArchiveEntry(fileName);
zipArchiveOutputStream.putArchiveEntry(entry);
// write(byte b[]):从指定的字节数组写入 b.length 个字节到此输出流
zipArchiveOutputStream.write(fileBytes);
}
// 写入此条目的所有必要数据。如果条目未压缩或压缩后的大小超过4 GB 则抛出异常
zipArchiveOutputStream.closeArchiveEntry();
} catch (IOException e) {
log.error(ExceptionUtils.getStackTrace(e));
}
}
/**
* 将文本内容写入到输出流中进行下载
* http://localhost:8080/fileServer/generateScript
*
* @param response
* @throws IOException
*/
@RequestMapping(value = "/generateScript", method = RequestMethod.GET)
public void generateScript(HttpServletResponse response) throws IOException {
List<String> alterSqlList = new ArrayList<>();
alterSqlList.add("ALTER TABLE BAS_PERSON_INFO ADD UPDATE_TIME DATE DEFAULT sysdate;");
alterSqlList.add("ALTER TABLE BAS_PERSON_INFO_HIS ADD UPDATE_TIME DATE DEFAULT sysdate;");
alterSqlList.add("ALTER TABLE BAS_PERSON_INFO_FORMER ADD UPDATE_TIME DATE DEFAULT sysdate;");
OutputStream outputStream = null;
try {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + System.currentTimeMillis() + ".sql");
outputStream = new BufferedOutputStream(response.getOutputStream());
outputStream.write("\n".getBytes());
outputStream.write("--Add columns to the table".getBytes());
for (String alterSql : alterSqlList) {
outputStream.write("\n".getBytes());
outputStream.write(alterSql.getBytes());
}
outputStream.write("\n".getBytes());
outputStream.write("\n".getBytes());
outputStream.write(("\n\n--蚩尤后裔提供技术支持 @ " + DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")).getBytes());
} finally {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
}
}
/**
* 解决 HttpServletResponse OutputStream Writer 输出数据乱码
* <p>
* http://localhost:8080/fileServer/showInitLog1
*
* @param response
* @throws IOException
*/
@RequestMapping(value = "/showInitLog1", method = RequestMethod.GET)
public void showInitLog1(HttpServletResponse response) throws IOException {
// 根据初始化操作的唯一编码查询操作的完整日志
List<String> dataList = new ArrayList<>();
dataList.add("2023-09-20 09:08:09 检查备份表、临时表与部标表字段差异开始.");
dataList.add("2023-09-20 09:08:10 单位扩展信息从临时表插入到正式表,影响条数0");
dataList.add("2023-09-20 09:08:11 将需要备份的数据主键ID放入到单位基本信息临时表,影响条数=0");
dataList.add("2023-09-20 09:08:12 同步全部区划2024本级单位信息完成.");
OutputStream outputStream = null;
try {
// 指定浏览器以UTF-8解码(编码与解码必须相同,否者就会出现乱码)
response.setHeader("content-type", "text/html;charset=utf-8");
outputStream = new BufferedOutputStream(response.getOutputStream());
for (String msg : dataList) {
// 指定以UTF-8编码输出
outputStream.write(msg.getBytes("utf-8"));
outputStream.write("<br/>".getBytes());
}
} finally {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
}
}
/**
* 解决 HttpServletResponse OutputStream Writer 输出数据乱码
* <p>
* http://localhost:8080/fileServer/showInitLog2
*
* @param response
* @throws IOException
*/
@RequestMapping(value = "/showInitLog2", method = RequestMethod.GET)
public void showInitLog2(HttpServletResponse response) throws IOException {
// 根据初始化操作的唯一编码查询操作的完整日志
List<String> dataList = new ArrayList<>();
dataList.add("2023-09-20 09:08:09 检查备份表、临时表与部标表字段差异开始.");
dataList.add("2023-09-20 09:08:10 单位扩展信息从临时表插入到正式表,影响条数0");
dataList.add("2023-09-20 09:08:11 将需要备份的数据主键ID放入到单位基本信息临时表,影响条数=0");
dataList.add("2023-09-20 09:08:10 重置单位基本信息临时表,影响条数=241");
dataList.add("2023-09-20 09:08:10 备份430300000 2021年以前的单位信息完成.");
dataList.add("2023-09-20 09:08:12 同步全部区划2024本级单位信息完成.");
OutputStream outputStream = null;
try {
// 指定以UTF-8编码输出
response.setCharacterEncoding("UTF-8");
// 指定浏览器以UTF-8解码(编码与解码必须相同,否者就会出现乱码)
response.setContentType("text/html;charset=utf-8");
outputStream = new BufferedOutputStream(response.getOutputStream());
for (String msg : dataList) {
outputStream.write(msg.getBytes());
outputStream.write("<br/>".getBytes());
}
} finally {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
}
}
/**
* http://localhost:8080/fileServer/export/csv
*
* 导出 csv 文件
*
* @param response /
* @throws IOException /
*/
@GetMapping("/export/csv")
public void exportCsv(HttpServletResponse response) throws IOException {
// 1. 动态生成 CSV 内容(模拟从数据库查询数据)
StringBuilder csvContent = new StringBuilder();
csvContent.append("姓名,年龄,部门\n");
csvContent.append("张三,25,技术部\n");
csvContent.append("李四,28,产品部\n");
// 2. 设置响应头(CSV 文件下载)
response.setContentType("text/csv;charset=gbk");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户信息表.csv", "UTF-8"));
// 3. 字符串写入响应流
try (OutputStream out = response.getOutputStream()) {
// CSV 是无格式的纯文本文件,Excel(Windows 主流版本)解析 CSV 的默认编码是 GBK/GB2312(而非 UTF-8)—— 这是历史原因(Windows 系统默认的中文编码是 GBK)
// 补充:如果用记事本打开 UTF-8 编码的 CSV,记事本会自动识别编码,所以不会乱码;但 Excel 不具备这个 “智能识别” 能力,必须匹配默认编码。
// 所以这里如果指定为utf-8,则下载的文件使用excel打开时,内容会乱码。
// StreamUtils.copy(csvContent.toString().getBytes("gbk"), out);
StreamUtils.copy(csvContent.toString(), Charset.forName("gbk"), out);
// 补充:如果想改用 UTF-8 编码(比如适配 Mac 系统),需要给 CSV 文件加UTF-8 BOM头(Excel 识别 UTF-8 BOM 才会用 UTF-8 解析)
// out.write(new byte[]{(byte)0xEF, (byte)0xBB, (byte)0xBF}); // 写入UTF-8 BOM头
// 但这种方式兼容性不如 GBK(旧版本 Excel 对 UTF-8 BOM 支持不佳),因此导出 CSV 给 Excel 用,行业内默认用 GBK 编码。
}
}
/**
* 获取被下载文件
*
* @param fileId :被下载文件ID
* @return
* @throws UnsupportedEncodingException
*/
private File getFile(String fileId) throws UnsupportedEncodingException {
String filePath = imageMap.get(fileId);
if (StringUtils.isBlank(filePath)) {
filePath = videoMap.get(fileId);
}
Assert.hasText(filePath, "文件ID错误,无法查询到被下载文件!");
URL url = DownloadFileController.class.getClassLoader().getResource(filePath);
Assert.notNull(url, fileId + ":资源文件不存在!");
String path = url.getPath();
// 对地址进行解码,以得到原始路径,防止中文乱码.
path = URLDecoder.decode(path, "utf-8");
return new File(path);
}
/**
* 获取被下载文件路径
*
* @param fileIds :被下载文件ID,多个时使用逗号分割,如 1,2,3,4
* @return
* @throws UnsupportedEncodingException
*/
private List<Path> listPath(String fileIds) throws UnsupportedEncodingException {
List<Path> filePaths = new ArrayList<>();
String[] split = fileIds.split(",");
for (String fileId : split) {
File file = this.getFile(fileId);
filePaths.add(file.toPath());
}
return filePaths;
}
private Map<String, InputStream> listInputStream(String fileIds) {
Map<String, InputStream> inputStreamMap = new HashMap<>();
String[] split = fileIds.split(",");
for (String fileId : split) {
String filePath = imageMap.get(fileId);
if (StringUtils.isBlank(filePath)) {
filePath = videoMap.get(fileId);
}
Assert.hasText(filePath, "文件ID错误,无法查询到被下载文件!");
InputStream inputStream = DownloadFileController.class.getClassLoader().getResourceAsStream(filePath);
Assert.notNull(inputStream, fileId + ":资源文件不存在!");
inputStreamMap.put(filePath, inputStream);
}
return inputStreamMap;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。