场景:页面按钮点击导出,后台处理数据后,返回字节流,通过浏览器能够自动下载
后台EasyExcel导出
@ApiOperation("导出")
@PostMapping("/export")
public void export(@RequestBody ExportSummaryParam param, HttpServletResponse response) {
exportService.exportSummary(param,response);
}
public interface IExportService {
void exportSummary(ExportSummaryParam param, HttpServletResponse response);
}
@Service
public class ExportServiceImpl implements IExportService {
@Override
public void exportSummary(ExportSummaryParam param, HttpServletResponse response) {
// 校验参数
// 查询提货汇总表
try {
// 设置响应头信息
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader("content-Length",String.valueOf(file.length()));
// 导出Excel
EasyExcel.write(response.getOutputStream(), SummaryExport.class)
.sheet("提货汇总")
.doWrite(exportList);
} catch (Exception e) {
e.printStackTrace();
}
}
}
前端请求导出
exportValid() {
console.log('param:', this.queryParam)
this.exportLoading = true
api.exportSummary(this.queryParam)
.then(res => {
if (res) {
this.$CommonUtils.downloadFileWithOptions({
data: res,
prefix: 'xxx',
extension: 'xlsx',
onSuccess: () => {
this.$message.success('导出成功!')
},
onError: (error) => {
this.$message.error('导出失败:' + error.message)
}
})
} else {
this.$message.error('导出失败!')
}
})
.finally(() => {
this.exportLoading = false
})
}
导出API
// 导出API
export function exportSummary(parameter) {
return request({
url: '/export',
method: 'post',
data: parameter,
responseType: 'blob'//很重要
})
}
下载工具类
// 下载工具类
/**
* 高级文件下载方法
* @param {Object} options - 下载配置项
* @param {Blob|ArrayBuffer} options.data - 文件数据
* @param {string} [options.prefix] - 文件名前缀
* @param {string} [options.extension] - 文件扩展名
* @param {string} [options.fileName] - 完整文件名(如果提供则忽略prefix和extension)
* @param {string} [options.timestamp] - 时间戳格式
* @param {Function} [options.onSuccess] - 下载成功回调
* @param {Function} [options.onError] - 下载失败回调
*/
export function downloadFileWithOptions(options) {
const {
data,
prefix = 'file',
extension = 'xlsx',
fileName,
timestamp = 'YYYYMMDDHHmmss',
onSuccess,
onError
} = options
try {
const finalFileName = fileName || `${prefix}${moment().format(timestamp)}.${extension}`
const blob = new Blob([data], {
type: getContentType(extension)
})
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// 针对 IE
window.navigator.msSaveOrOpenBlob(blob, finalFileName)
} else {
// 现代浏览器
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.download = finalFileName
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
}
// 处理成功回调
if (typeof onSuccess === 'function') {
onSuccess()
}
return true
} catch (error) {
console.error('文件下载失败:', error)
// 处理错误回调
if (typeof onError === 'function') {
onError(error)
}
return false
}
}
/**
* 获取文件类型
* @param {string} extension - 文件扩展名
* @returns {string} MIME类型
*/
function getContentType(extension) {
const mimeTypes = {
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
xls: 'application/vnd.ms-excel',
pdf: 'application/pdf',
doc: 'application/msword',
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
txt: 'text/plain',
csv: 'text/csv'
// 可以根据需要添加更多类型
}
return mimeTypes[extension] || 'application/octet-stream'
}