原理
基于HTTP1.1协议RFC2616的19.5.1:
只要遵守协议要求,SpringMVC、Servlet甚至手写WebServer都可以实现下载功能。
流程如下:
实现
1、搭建好SpringMVC环境
2、创建Controller
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.mysql.cj.result.Row;
/**
*@author Edward
*@date 2020年7月5日---上午8:48:42
*/
@RequestMapping("/demo")
@Controller
public class DemoController {
@RequestMapping(
value="/download.do",
// 直接在这里setContentType 很流弊
produces="image/png")
@ResponseBody
public byte[] download(HttpServletResponse response){
System.out.println("DemoController.download()");
//response.setHeader("Content-Type", "image/png");
String file = "演示图片.png";
try {
// 请求头只能允许8859-1,因此需要转码
file = URLEncoder.encode(file,"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//response.setContentType("image/png");
response.setHeader("Content-Disposition", "attachment; filename=\""+file+"\"");
byte[]bytes = createPNG();
return bytes;
}
@RequestMapping(
value="/export.do",
// 直接在这里setContentType 很流弊
produces="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@ResponseBody
public byte[] export(HttpServletResponse response) {
System.out.println("DemoController.export()");
//response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
String file = "Excel表格.xlsx";
try {
// 请求头只能允许8859-1,因此需要转码
file = URLEncoder.encode(file,"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setHeader("Content-Disposition", "attachment; filename=\""+file+"\"");
byte[]bytes = createExcel();
return bytes;
}
private byte[] createExcel() {
System.out.println("DemoController.createExcel()");
byte[]excel=null;
try ( // 获取字节输出流 酱油瓶 内存操作 快
ByteArrayOutputStream out = new ByteArrayOutputStream();
// POI API 生成Excel
XSSFWorkbook workbook = new XSSFWorkbook();){
// 在Excel工作簿中创建一个工作表
XSSFSheet sheet = workbook.createSheet("Demo");
//创建一个九九乘法表
for (int i = 1; i <= 9; i++) {
XSSFRow row = sheet.createRow(i-1);
for (int j = i; j <=9 ; j++) {
XSSFCell cell = row.createCell(j-1);
cell.setCellValue(i+"*"+j+"="+i*j);
}
}
// // 创建行
// XSSFRow row = sheet.createRow(0);
//
// // 在行中创建数据格
// XSSFCell cell = row.createCell(0);
//
// cell.setCellValue("Hello World!");
workbook.write(out);
excel= out.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return excel;
}
private byte[] createPNG() {
System.out.println("DemoController.createPNG()");
// BufferedImage img = new BufferedImage(100, 50, BufferedImage.TYPE_3BYTE_BGR);
// // 黄
// img.setRGB(50, 25, 0xffff00);
byte[] png=null;
try (
// 获取字节输出流 酱油瓶 内存操作 快
ByteArrayOutputStream out = new ByteArrayOutputStream()){
// 传个现有的图片
File file = new File("C:\\Users\\Administrator\\Desktop\\images\\胖迪.jpg");
BufferedImage img = ImageIO.read(file);
ImageIO.write(img, "png", out);
png= out.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return png;
}
}
注意:由于SpringMVC没有专门配置这个功能的API,因此需要手动调用response修改Content-Type以及Content-Disposition。 文件可以用字节流读取并取出。
另外:Content-Type可能配置不上,建议直接在RequestMapping中配置。
3、创建页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Download</title>
</head>
<body>
<h1>文件下载功能</h1>
<p>下载图片:
<a href="demo/download.do">图片</a>
</p>
<p>导出Excel:
<a href="demo/export.do">下载</a>
</p>
</body>
</html>
点击即可下载指定文件内容。