记录批量文件下载
问题:前端都是单独文件的下载(根据oss文件地址,使用a标签下载);现在需要将文件进行批量下载,打包为zip压缩包。
思路:一种是在前端把所有oss文件地址传入后端,打为压缩包,传输的数据量较大,前端不好处理;另一个传入key值,在后端进行文件查询,再打为压缩包;
本质上,都是在后端将所有文件打为压缩包,只是根据前端传输参数量处理方式不一样;
一、前端
- 使用key值,参数量少,get请求;
window.location.href=process.env.BASE_API + `/simple/demo/batchDownload/${ids}`;
- 传输所有url,参数数据量大,拼接form表单post请求;
downContracts(){
this.changeFlag = 0;
var fileName = '';
this.downIds = '';
for(let m=0;m<this.nowList.length;m++){
this.downIds += this.nowList[m].id+",";
}
if (this.downIds.length > 0) {
this.downIds = this.downIds.substr(0, this.downIds.length - 1);
request({
method: 'post',
url: '/simple/demo/searchContract/'+this.downIds,
data: {
}
}).then(res => {
if (res.data.success) {
var urlList = [];
for(let i in res.data.obj){
urlList.unshift(res.data.obj[i].fillTemplateUrl);
}
let files = urlList.reverse();
if(files.length>1){
//批量合同下载
fileName = this.nowList[0].name;
console.log("数组:"+files)
var filesStr = '';
for(let i=0;i<files.length;i++){
filesStr += files[i]+",";
}
if (filesStr.length > 0) {
filesStr = filesStr.substr(0, filesStr.length - 1);
}
console.log("路径:"+filesStr)
var urlsStr = filesStr;
var requstUrl = process.env.BASE_API + `/simple/demo/downBatchContract`;
console.log("参数:"+urlsStr+fileName)
var pre = "<form action="+requstUrl+" method='post' target='_blank' name='count_form' style='display:none'>"
document.write(pre);
document.write("<input type='hidden' name='urlsStr' value='"+filesStr+"'/>");
document.write("<input type='hidden' name='fileName' value='"+fileName+"'/>");
document.write("</form>");
document.count_form.submit();
//this.changeFlag = 1;
location.reload(true);
}else{
window.open(files[0],'_blank')//单条数据,直接下载
}
}else{
this.$message({
type:'warning',
message:res.data.msg
});
}
})
}else{
this.$message({
showClose: true,
message: '请选择一条数据!',
type: 'warning'
});
}
},
二、后端
这里演示key值传输的后端,传url
首先需要一个工具类,下载文件字节码;
public class UrlFilesToZip {
private static final Logger logger = LoggerFactory.getLogger(UrlFilesToZip.class);
//根据文件链接把文件下载下来并且转成字节码
public byte[] getImageFromURL(String urlPath) {
byte[] data = null;
InputStream is = null;
HttpURLConnection conn = null;
try {
URL url = new URL(urlPath);
data = readInputStream(url.openStream());
} catch (MalformedURLException e) {
logger.error("MalformedURLException", e);
} catch (IOException e) {
logger.error("IOException", e);
}
return data;
}
public byte[] readInputStream(InputStream is) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = -1;
try {
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
baos.flush();
} catch (IOException e) {
logger.error("IOException", e);
}
byte[] data = baos.toByteArray();
try {
is.close();
baos.close();
} catch (IOException e) {
logger.error("IOException", e);
}
return data;
}
}
根据传入参数,获取文件地址,转为字节码,一个个输出到zip中去;
@ApiOperation(value = "放款通知书批量下载", notes = "放款通知书批量下载")
@ApiImplicitParams({
@ApiImplicitParam(name = "token", value = "token令牌", required = true, paramType = "header"),
})
@GetMapping(value = "/batchDownload/{ids}")
@UnAuthentication
public void export(@PathVariable("ids") String ids, HttpServletResponse response){
//查询所有合同地址url
String[] flowIds = ids.split(",");
List<String> uuids = Arrays.stream(flowIds).map(id->{
String uuid = "";
QhhryVankeFlow flow = qhhryVankeFlowService.get(Long.parseLong(id));
if(flow != null){
uuid = flow.getUuid();
}
return uuid;
}).collect(Collectors.toList());
List<VankFacilityContract> allContract = new ArrayList<>();
for(String uuid : uuids){
if(uuid!=null && !uuid.equals("")){
List<SimpleContract> contracts = (List<SimpleContract>) this.list(uuid,"FK").getObj();
allContract.addAll(contracts);
}
}
//根据合同url地址,打为压缩包
try {
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
String fileEnd = sf.format(new Date());
String resultFileName = "放款通知书-"+fileEnd+".zip";
String filename = new String(resultFileName.getBytes("UTF-8"), "ISO8859-1");//控制文件名编码
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(bos);
UrlFilesToZip s = new UrlFilesToZip();
int idx = 1;
for (SimpleContract contract : allContract) {
String resultName = contract.getFilleUrl().substring(contract.getFilleUrl().lastIndexOf("/")+1);
zos.putNextEntry(new ZipEntry(resultName));
byte[] bytes = s.getImageFromURL(contract.getFilleUrl());
zos.write(bytes, 0, bytes.length);
zos.closeEntry();
idx++;
}
zos.close();
response.setContentType("application/force-download");// 设置强制下载,不打开新标签
response.addHeader("Content-Disposition", "attachment;fileName=" + filename);// 设置文件名
OutputStream os = response.getOutputStream();
os.write(bos.toByteArray());
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}