Java+Vue導(dǎo)出zip壓縮包前后端實現(xiàn)
本例實現(xiàn)批量導(dǎo)出二維碼圖片文件,將所有的圖片放在一個zip壓縮包中。
實現(xiàn)步驟:
1、查詢數(shù)據(jù)循環(huán)生成二維碼圖片
2、將生成的二維碼圖片放在一個壓縮包中,通過數(shù)據(jù)流返回給前端
- 通過cn.hutool.extra.qrcode.QrCodeUtil生成二維碼圖片,得到byte[]
- 通過java.util.zip.ZipOutputStream將byte[]寫入壓縮包
- 通過java.io.ByteArrayOutputStream返回完整的byte[]
- 全部寫入完成后,得到完整的byte[]輸出到HttpServletResponse
- 設(shè)置HttpServletResponse響應(yīng)頭數(shù)據(jù),標(biāo)記為文件下載
3、前端Vue得到數(shù)據(jù)流實現(xiàn)下載
- 調(diào)用后端接口,設(shè)置responseType: 'blob'
- 通過window.navigator.msSaveBlob下載文件
一、后端接口生成zip壓縮文件byte[]
/**
* 導(dǎo)出二維碼
*
*/
@RequestMapping(value = "/exportQrcode")
public void exportQrcode(HttpServletRequest request, HttpServletResponse response, ProQrcode proQrcode) throws IOException {
// Step.1 組裝查詢條件
// ... 此處省略數(shù)據(jù)查詢條件...
// 查詢數(shù)據(jù)
List<ProQrcode> list = service.list(queryWrapper);
int width = 800;
if (StringUtils.isNotBlank(widthStr)) {
width = Integer.parseInt(widthStr);
}
byte[] data = genQrcodeImg(list, width);
zip(response, data);
}
/**
* 批量生產(chǎn)圖片zip壓縮包數(shù)據(jù)
* */
private byte[] genQrcodeImg(List<ProQrcode> list, int width) {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream)) {
for (int i = 0; i < list.size(); i++) {
ProQrcode qrcode = list.get(i);
try {
// 添加到zip,設(shè)置文件名,后綴.png
zip.putNextEntry(new ZipEntry(String.format("%d.%s.png", i + 1, qrcode.getCode())));
// 查詢是否配置了logo,如果有l(wèi)ogo,則把logo添加到二維碼中
BufferedImage logo = CustomerBrandCache.getLogo(qrcode.getCustomerBrandId());
QrConfig config = new QrConfig();
config.setWidth(width).setHeight(width);
if (logo != null) {
config.setImg(logo);
}
// 生成二維碼圖片
byte[] bytes = QrCodeUtil.generatePng(qrcode.getLinkUrl(), config);
// 將byte[]寫入到壓縮包中
IOUtils.write(bytes, zip);
zip.flush();
zip.closeEntry();
} catch (IOException e) {
log.error("addQrcode,error:", e);
}
}
return outputStream.toByteArray();
} catch (Exception e) {
log.error("", e);
}
return new byte[0];
}
/**
* 生成zip文件,設(shè)置響應(yīng)頭為文件下載
*/
private void zip(HttpServletResponse response, byte[] data) throws IOException {
response.reset();
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment; filename=\"qrcode.zip\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(data, response.getOutputStream());
}
通過cn.hutool.extra.qrcode.QrCodeUtil生成二維碼圖片,得到byte[]通過java.util.zip.ZipOutputStream將byte[]寫入壓縮包通過java.io.ByteArrayOutputStream返回完整的byte[]全部寫入完成后,得到完整的byte[]輸出到HttpServletResponse設(shè)置HttpServletResponse響應(yīng)頭數(shù)據(jù),標(biāo)記為文件下載
二、Vue前端調(diào)用后端接口實現(xiàn)下載
/**
* 導(dǎo)出二維碼數(shù)據(jù)
*/
export const exportQrcode = async (name, params) => {
const data = await defHttp.get({ url: Api.exportQrcode, params, responseType: 'blob', timeout: 30000 }, { isTransformResponse: false })
if (!data) {
createMessage.warning('文件下載失敗')
return
}
if (!name || typeof name != 'string') {
name = '導(dǎo)出文件'
}
const blobOptions = { type: 'application/octet-stream' }
const fileSuffix = '.zip'
debugger
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data], blobOptions), name + fileSuffix)
} else {
const url = window.URL.createObjectURL(new Blob([data], blobOptions))
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', name + fileSuffix)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) //下載完成移除元素
window.URL.revokeObjectURL(url) //釋放掉blob對象
}
}
調(diào)用后端接口,設(shè)置responseType: 'blob'通過window.navigator.msSaveBlob下載文件