Vue +springboot 导出excel
两种实现方式:1.后台返回json,前台通过xlsx解析,然后生成excel文件;2.后台返回文件流;第一种方式:贴出前台代码,后台的就不需要了吧,就是很简单的json数据;//导出exportTable() {var jsono = [{"应用名字" : "appname","关键字" : "keyword"...
·
两种实现方式:1.后台返回json,前台通过xlsx解析,然后生成excel文件;2.后台返回文件流;
第一种方式:贴出前台代码,后台的就不需要了吧,就是很简单的json数据;
//导出
exportTable() {
var jsono = [{
"应用名字" : "appname",
"关键字" : "keyword",
}]
var keyMap = [];
var valueMap = [];
var list1 = []
for (var k in jsono[0]) {
keyMap.push(k)
valueMap.push(jsono[0][k])
}
for (var i=0;i<this.dataList.length;i++) {
list1[i] = []
for (var j in valueMap) {
list1[i][keyMap[j]]= this.dataList[i][valueMap[j]]
}
}
var ws = xlsx.utils.json_to_sheet(list1);
var wb = xlsx.utils.book_new();
xlsx.utils.book_append_sheet(wb, ws, "People");//sheet名称
let out = xlsx.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array"
});
try {
fileSaver.saveAs(
new Blob([out], {
type: "application/octet-stream"
}),
"列表.xlsx"
);
} catch (e) {
// 错误处理方式
}
return out;
},
第二种:同样,先贴出前台代码:
// 导出方法
exportTable(){
this.$http({
url: this.$http.adornUrl('/*/getExportData'),//获取文件流的接口路径
method: 'post',
data: {//请求参数
"id":"12"
},
responseType: 'blob' // 表明返回服务器返回的数据类型 很重要!!
}).then((res) => {
//将文件流转成blob形式
const blob = new Blob([res.data],{type: 'application/vnd.ms-excel'});
let filename ='1.xls';
//创建一个超链接,将文件流赋进去,然后实现这个超链接的单击事件
const elink = document.createElement('a');
elink.download = filename;
elink.style.display = 'none';
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
}).catch(error => {
this.$message.error('导出失败');
// console.log(error)
})
},
后台代码我不想贴了,因为用的jxl的技术,很老,我就只贴出遇到的问题跟解决方式吧:
(1)第一个问题:前台不识别文件流
responseType: 'blob' // 表明返回服务器返回的数据类型 很重要!!
这个一定要加在请求头里面,否则识别不了文件流
(2)第二个问题:跨域
因为是前后端分离,IP跟端口肯定不一样,浏览器不接受这种跨域返回的文件流,所以需要在response的header里面加一条属性:
response.setHeader("Access-Control-Allow-Origin", "http://***:8001");//解决跨域
网上有很多说放个*就行,像这样:
response.setHeader("Access-Control-Allow-Origin", "*");//解决跨域
但是我这试了不行,所以就把前台的具体IP跟端口写进去了,反正是管用。
//费了很大功夫,把后台返回文件流的代码更新成poi方式了,然后我发现,后台jxl方式,需要解决跨域,而改成poi就不需要跨域了,很神奇,也没空去了解更多;先把后台代码记录一下:
public static void export(List<Map<String,Object>> list, LinkedHashMap<String, String> fieldMap,String filName,
HttpServletResponse response) throws IOException {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(filName+"1");//新建sheet
HSSFCellStyle contextstyle =wb.createCellStyle();
HSSFRow row = null;
int rowIndex = 0 ;
row = sheet.createRow(0);
row.setHeight((short) (22.50 * 20));//设置行高
// 定义存放英文字段名和中文字段名的数组
String[] enFields = new String[fieldMap.size()];
String[] cnFields = new String[fieldMap.size()];
// 填充数组
int count = 0;
for (Map.Entry<String, String> entry : fieldMap.entrySet()) {
enFields[count] = entry.getKey();
cnFields[count] = entry.getValue();
count++;
}
//设置表头
for(int i=0; i<cnFields.length;i++){
row.createCell(i).setCellValue(cnFields[i]);
}
for (int i = 0; i < list.size(); i++) {
if(rowIndex>65535 ){
sheet = wb.createSheet(filName+"2");
row = sheet.createRow(0);
row.setHeight((short) (22.50 * 20));//设置行高
//设置表头
for(int k=0; k<cnFields.length;k++){
row.createCell(k).setCellValue(cnFields[k]);
}
}
row = sheet.createRow(i + 1);
for(int j = 0; j<enFields.length;j++) {
Object data = list.get(i).get(enFields[j]);//获取第i行第j列所放数据
HSSFCell contentCell = row.createCell(j);
boolean isNum = false;
boolean isInteger = false;
if (data != null || "".equals(data)) {
//判断data是否为数值型
isNum = data.toString().matches("^(-?\\d+)(\\.\\d+)?$");
//判断data是否为整数(小数部分是否为0)
isInteger=data.toString().matches("^[-\\+]?[\\d]*$");
}
if(isNum){
HSSFDataFormat df = wb.createDataFormat(); // 此处设置数据格式
if (isInteger) {
//数据格式只显示整数
contextstyle.setDataFormat(df.getBuiltinFormat("0"));
// 设置单元格内容为double类型
contentCell.setCellValue(data.toString());
}else{
//保留两位小数点
contextstyle.setDataFormat(df.getBuiltinFormat("0.00"));
// 设置单元格内容为double类型
contentCell.setCellValue(Double.parseDouble(data.toString()));
// 设置单元格格式
contentCell.setCellStyle(contextstyle);
}
}else {
contentCell.setCellValue(list.get(i).get(enFields[j]) == null ? "" : list.get(i).get(enFields[j]).toString());
}
}
rowIndex++;
}
// 遍历集合数据,产生数据行
sheet.setDefaultRowHeight((short) (16.5 * 20));
//列宽自适应
for (int i = 0; i <= 13; i++) {
sheet.autoSizeColumn(i);
}
response.setContentType("application/vnd.ms-excel;charset=utf-8");
OutputStream os = response.getOutputStream();
response.setHeader("Content-disposition", "attachment;filename=balancelog.xls");//默认Excel名称
wb.write(os);
os.flush();
os.close();
}
更多推荐
已为社区贡献1条内容
所有评论(0)