需求
每个订单页面导出数据【订单数据量较大】
思考
先罗列集中导出的方式
1. 纯前端实现导出(数据量小)
1. 使用插件xlsx,xlsx-style(修改样式)
2. 下载Export2Excel,Blob文件,不过如果没有用到转流的问题可以不需要下载blob.js
3. 重要代码
//这里是我下载的源码之后自行根据需求改动的,设置样式或者做一些业务改动参照下面的代码
export function export_json_to_excel (th, jsonData, defaultTitle, mode) {
/* original data */
var data = jsonData
data.unshift(th)
var ws_name = 'SheetJS'
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data)
/*设置worksheet每列的最大宽度*/
const colWidth = data.map((row) =>
row.map((val) => {
/*先判断是否为null/undefined*/
if (val == null) {
return { wch: 10 }
} /*再判断是否为中文*/
else if (val.toString().charCodeAt(0) > 255) {
return { wch: val.toString().length * 2 }
} else {
return { wch: val.toString().length }
}
})
)
/*以第一行为初始值*/
let result = colWidth[0]
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]['wch'] < colWidth[i][j]['wch']) {
result[j]['wch'] = colWidth[i][j]['wch']
}
}
}
ws['!cols'] = result
/* add worksheet to workbook */
wb.SheetNames.push(ws_name)
wb.Sheets[ws_name] = ws
var dataInfo = wb.Sheets[wb.SheetNames[0]];
// 设置样式以及具体的值
let style = {
font: {
color: { rgb: 'ff0000' },
bold: true,
},
alignment: {
horizontal: "center",
vertical: "center"
},
fill: {
fgColor: { rgb: "e2efda" },
}
}
let bac = {
fill: {
fgColor: { rgb: "e2efda" },
}
}
//这里给指定的列设置背景颜色
let arr1 = ["A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1", "I1", "J1", "K1", "L1", "M1", "N1", "O1", "P1", "Q1", "R1", "S1", "T1", "U1", "V1", "W1", "X1", "Y1", "Z1", "AA1", "AB1", "AC1", "AD1", "AE1"];
let arr = ["B1", "F1", "I1", "J1", "K1"];
if (mode === 'spec') {
for (let i = 0; i < arr1.length; i++) {
dataInfo[arr1[i]].s = bac
}
for (let i = 0; i < arr.length; i++) {
dataInfo[arr[i]].s = style
}
}
var wbout = XLSX.write(wb, {
bookType: 'xls',
bookSST: false,
type: 'binary'
})
var title = defaultTitle || 'excel-list'
saveAs(
new Blob([s2ab(wbout)], { type: 'application/octet-stream' }),
title + '.xls'
)
}
4. 使用
let excel = await import("@/js/Export2Excel");
let tHeader, tFields, tFileName;
if (from === "statistic") {
tHeader = ["病案号", "院区", "病房", "科室", "调阅医生", "调阅时间", "调阅类型"];
tFields = ["mrid", "hospitalName", "consultRoomName", "departmentName", "doctorName", "opdViewTime", "opdViewTypeName"];
tFileName = "调阅统计";
} else {
tHeader = ["病案号", "患者姓名", "就诊院区", "就诊科室", "就诊医生", "就诊时间", "调阅状态", "调阅时间"];
tFields = ["mrid", "patientName", "hosDistrictName", "departmentName", "doctorName", "consultTime", "readEMR", "opdViewTime"];
tFileName = "挂号明细";
}
const data = this.datasource.list.map(v => tFields.map(j => {
if (j === "readEMR") return v[j] ? "已调阅" : "未调阅";
else return v[j];
}));
excel.export_json_to_excel(tHeader, data, tFileName);// 表头名称,数据字段,导出表名称
2. 纯前端实现导出(数据量大),建议订单还是需要后端做导出,数据量超过几万条。
let str =
"订单号,病案号,患者姓名,申请人,申请时间,是否继续复印,复印项目,订单金额,接收方式,订单状态\n";
this.$store.state.resList[3].list.map(v => {
str += `${v.orderNumber}\t,${v.mrid}\t,${v.patientName}\t,${v.applyPeople}\t,${v.applyTime}\t,${v.isPathologyName}\t,${v.printReceptionMridList}\t,${v.orderAmount}\t,${v.mailName}\t,${v.status},\n`;
});
let blob = new Blob([str], { type: "text/plain;charset=utf-8" });
blob = new Blob([String.fromCharCode(0xfeff), blob], {
type: blob.type
});
let url = window.URL.createObjectURL(blob);
let link = document.createElement("a");
link.href = url;
link.download = "全部订单.xls";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
3. 配合后端做数据导出
// var that = this;
this.$axios({
method: "get",
url: `${window.config.server}/Order/ExprotOrderList`,
params: {
fileName: "待邮寄",
PickupCode: "",
ReceptionType: this.hdwaydata,
OrderIds: orderid,
Status: "3",
EndTime: this.AplTime.endTime,
BeginTime: this.AplTime.startTime
},
responseType: "blob",
// transformResponse: [
// function(data) {
// console.log(data);
// var reader = new FileReader();
// reader.readAsText(data, "GBK");
// reader.onload = function(e) {
// var music = JSON.parse(reader.result);
// console.log(music);
// that.data = music;
// };
// return data;
// }
// ],
// headers: {
// "X-Requested-With": "XMLHttpRequest",
// "Content-Type": "application/x-www-form-urlencoded"
// }
}).then(res => {
console.log(res);
const link = document.createElement("a");
let blob = new Blob([res.data], {
type: "application/vnd.ms-excel; charset=UTF-8"
});
link.style.display = "none";
link.href = URL.createObjectURL(blob);
link.download = res.headers["content-disposition"];
link.setAttribute("download", "待邮寄" + ".xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
4. 可能存在问题
4.1 不同的请求可实现不同的结果(原声请求,axios)
最简单的办法:
// 直接用后端的链接
window.location = `${
window.config.server
}/Order/ExprotOrderList?EndTime=${
this.AplTime.endTime === null ? "" : this.AplTime.endTime
}&BeginTime=${
this.AplTime.startTime === null ? "" : this.AplTime.startTime
}&Status=3&ReceptionType=&ISMail=1&OrderIds=${orderid}&fileName=待邮寄`;
4.2 可能引起的乱码问题
一般情况下按照第3个代码是没有乱码的,乱码出现原因有两点1. 转换blob没成功,有其他请求在干扰(mock)2. 不是utf-8格式
解决办法: 1. 可以去掉引入mock 2. 用原生请求,不用axios
let xhr = new XMLHttpRequest();
xhr.open(
"get",
`${window.config.server}/Order/ExprotOrderList?EndTime=${
this.AplTime.endTime === null ? "" : this.AplTime.endTime
}&BeginTime=${
this.AplTime.startTime === null ? "" : this.AplTime.startTime
}&Status=3&ReceptionType=&ISMail=1&OrderIds=${orderid}&fileName=待邮寄`,
true
);
xhr.send();
xhr.onreadystatechange = function(res) {
// 判断服务器是否正确响应
console.log(xhr);
xhr.responseType = "blob";
if (xhr.readyState === 4 && xhr.status === 200) {
const link = document.createElement("a");
let blob = new Blob([xhr.responseText], {
type: "application/vnd.ms-excel; charset=UTF-8"
});
link.style.display = "none";
link.href = URL.createObjectURL(blob);
// link.download = xhr.headers["content-disposition"];
link.setAttribute("download", "待邮寄");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
};
因为加入mock的话,即使不使用mock.mock,也会拦截请求
网友评论