はじめに
これは Excel テーブルのインポートとエクスポートによく使用される機能ですが、私の場合は 3 層のヘッダー テーブルなど、
複雑なヘッダーを含むテーブルのエクスポートとインポートが頻繁に行われます。ネットで調べた結果、非常に簡単なエクスポートとインポートの方法を見つけました。もちろん、これは純粋なフロントエンド バージョンであり、ページングをダウンロードするのが簡単ではない場合もあります。したがって、実際の作業では、エクスポートは引き続きバックエンドの責任となります。
エフェクト画像
は、表のスタイルです。3 層のヘッダーです。
「エクスポート」をクリックした後の効果と表の形式は次のとおりです。
[インポート]をクリックした後の効果と取得されたデータ形式は次のとおりです。
使い方の紹介
1. プラグインをダウンロードするには、次のコマンドを入力します: npm install -S file-saver xlsx
2. これをページに導入します。インポートとエクスポートを記述する必要があるテーブル ページに直接記述するだけです。
3. この ID をフォームにバインドします。エクスポート時にデータを取得するために使用されます
ここで、データを取得してインポート後にバックエンドに渡したい場合は、ループしてこの位置で新しい配列にプッシュし、その配列をループの外のバックエンドに渡します。
コード部分 (純粋なフロントエンドのインポートおよびエクスポート)
<template>
<div>
<div class="titleBtn">
<!-- 导出Excel -->
<el-button
@click="exportClick"
type="primary"
size="small"
style="margin: 0 20px"
icon="el-icon-folder-opened"
>导出</el-button
>
<!-- 导入Excel -->
<el-upload
action="/上传文件的接口"
:on-change="onChange"
:auto-upload="false"
:show-file-list="false"
accept=".xls, .xlsx"
ref="upload"
:multiple="true"
>
<el-button type="warning" icon="el-icon-folder-add" size="small"
>导入</el-button
>
</el-upload>
</div>
<el-table :data="tableData" style="width: 100%" id="mainTable">
<el-table-column prop="date" label="日期" width="150"> </el-table-column>
<el-table-column label="配送信息">
<el-table-column prop="name" label="姓名" width="120">
</el-table-column>
<el-table-column label="地址">
<el-table-column prop="province" label="省份" width="120">
</el-table-column>
<el-table-column prop="city" label="市区" width="120">
</el-table-column>
<el-table-column prop="address" label="地址" width="300">
</el-table-column>
<el-table-column prop="zip" label="邮编" width="120">
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
</div>
</template>
<script>
import FileSaver from "file-saver";
import * as XLSX from "xlsx";
export default {
data() {
return {
tableData: [
{
date: "2016-05-02",
name: "王小虎",
province: "上海",
city: "普陀区",
address: "上海市普陀区金沙江路 1518 弄",
zip: 200333,
},
],
};
},
methods: {
//导出
exportClick() {
//第一个参数是到处后文件名,第二个是id绑定表格dom
this.exportExcel("test", "mainTable");
},
//转换数据
exportExcel(filename, tableId) {
var xlsxParam = { raw: true }; // 导出的内容只做解析,不进行格式转换
var table = document.querySelector("#" + tableId).cloneNode(true);
var wb = XLSX.utils.table_to_book(table, xlsxParam);
/* 获取二进制字符进行输出 */
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
try {
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
filename + ".xlsx"
);
} catch (e) {
if (typeof console !== "undefined") {
console.log(e, wbout);
}
}
return wbout;
},
//导入
onChange(file, fileList) {
this.readExcel(file); // 调用读取数据的方法
},
// 读取数据
readExcel(file) {
let that = this;
if (!file) {
//如果没有文件
return false;
} else if (!/.(xls|xlsx)$/.test(file.name.toLowerCase())) {
this.$message.error("上传格式不正确,请上传xls或者xlsx格式");
return false;
}
const fileReader = new FileReader();
fileReader.onload = (ev) => {
try {
const data = ev.target.result;
const workbook = XLSX.read(data, {
type: "binary",
});
if (workbook.SheetNames.length >= 1) {
this.$message({
message: "导入数据表格成功",
showClose: true,
type: "success",
});
}
const wsname = workbook.SheetNames[0]; //取第一张表
const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格内容
console.log("生成json:", ws);
// that.tableData = [];
for (var i = 2; i < ws.length; i++) {
let sheetData = {
// 键名为绑定 el 表格的关键字,值则是 ws[i][对应表头名]
date: ws[i]["日期"],
name: ws[i]["配送信息"],
province: ws[i]["__EMPTY"],
city: ws[i]["__EMPTY_1"],
address: ws[i]["__EMPTY_2"],
zip: ws[i]["__EMPTY_3"],
};
console.log("上传的数据:", sheetData);
//添加到表格中
that.tableData.push(sheetData);
//正常导入需要拿到上传的数据就在这从新弄个数组push进去,然后传给后台,后台保存后查询表格返给前端。
}
this.$refs.upload.value = "";
} catch (e) {
console.log(e);
return false;
}
};
// 如果为原生 input 则应是 files[0]
fileReader.readAsBinaryString(file.raw);
},
},
};
</script>
<style scoped>
.titleBtn {
display: flex;
margin: 20px 0;
}
</style>
バックエンドを使用した 2 つの方法
上記の純粋なフロントエンドの書き込み方法には問題があるため、ページングがある場合はデータを取得できません。
または、データが大きすぎるため、ダウンロードが非常に遅くなり、停止します。したがって、基本的に作業内容はすべてバックエンドによってエクスポートされ、ダウンロード リンクが生成されます。
さらに 2 つの方法を紹介します。
1、ラベルダウンロード
この方法の核心は、バックエンドがダウンロード リンクを直接生成し、フロントエンドが必要とするのは A タグを生成してダウンロードすることだけであるということです。最も一般的に使用されるものの 1 つ
daochu(){
// A标签导出方法:通过生成一个A标签然后触发后台传过来的下载链接完成导出
//核心注意需要给请求的格式改为:responseType: "blob",
this.axios
.post(
url, {}, {
token: true,
responseType: "blob",
}
)
.then((res) => {
if (res.status == 200) {
//拿到后台发过来的下载链接
let url = window.URL.createObjectURL(new Blob([res.data]));
//生成一个A标签
let link = document.createElement("a");
//样式设为none,没有大小,不占位置
link.style.display = "none";
//把链接地址给href
link.href = url;
//下载后的名字,用时间来标注避免重复
let filename = new Date().getTime() + ".xlsx";
//给A标签添加属性download,值为上面的名字
link.setAttribute("download", filename);
//在页面的尾部插入元素A标签
document.body.appendChild(link);
//点击A标签,这样就触发下载了。
link.click();
} else if (res.data.code != 200) {
this.$message("暂无数据");
}
this.exporloading = false;
})
.catch((err) => {
this.exporloading = false;
});
}
2. 上記のフロントエンド方法を使用して、ページングを行わずにバックエンドに完全な形式のデータを直接渡します。
次に、このデータを使用してテーブルの配列に値を割り当て、テーブル dom をエクスポート メソッドに渡してダウンロードします。
バックエンドがすべてのデータを提供せず、データがそれほど多くないため、すべてのデータを取得するという目的を達成するために、フロントデスクを循環して各ページのデータを配列にマージするだけです。しかし、これはお勧めできません。
ここで this.$excels はこのメソッドをカプセル化し、main.js にプロトタイプを割り当てたものです。方法は上記と同じです。
パッケージの外観は基本的に上記と同様です。
これはループで取得されたページ データです。85 項目すべてが取得され、tableData2 配列にコピーされ、テーブルの dom が取得され、すべてのデータのテーブルをエクスポートできます。
テーブル内の複数シートを一度に読み出して書き込む
場合によっては、最初のシート以上のものが必要になることがあります。テーブル内に多数のシートがあり、各シートのフィールドが異なる場合があります。したがって、上記のメソッドに少し変更を加えて、次のように書くことができます。
readExcel メソッドを変更するだけです。修正内容は主に各シートのデータを読み込むループの追加です。
// 读取数据
readExcel(file) {
let that = this;
if (!file) {
//如果没有文件
return false;
} else if (!/.(xls|xlsx)$/.test(file.name.toLowerCase())) {
this.$message.error("上传格式不正确,请上传xls或者xlsx格式");
return false;
}
const fileReader = new FileReader();
fileReader.onload = (ev) => {
try {
const data = ev.target.result;
const workbook = XLSX.read(data, {
type: "binary",
});
if (workbook.SheetNames.length >= 1) {
//读取到表中sheet
this.$message({
message: "导入数据表格成功",
showClose: true,
type: "success",
});
}
for (var i = 0; i < workbook.SheetNames.length; i++) {
const wsname = workbook.SheetNames[i]; //取第一张表
const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格内容
console.log("生成json:", ws);
// that.tableData = [];
// for (var i = 2; i < ws.length; i++) {
// let sheetData = {
// // 键名为绑定 el 表格的关键字,值则是 ws[i][对应表头名]
// date: ws[i]["日期"],
// name: ws[i]["配送信息"],
// province: ws[i]["__EMPTY"],
// city: ws[i]["__EMPTY_1"],
// address: ws[i]["__EMPTY_2"],
// zip: ws[i]["__EMPTY_3"],
// };
// console.log("上传的数据:", sheetData);
// //添加到表格中
// that.tableData.push(sheetData);
// //正常导入需要拿到上传的数据就在这从新弄个数组push进去,然后传给后台,后台保存后查询表格返给前端。
// }
}
this.$refs.upload.value = "";//清空上传列表,不能放在循环内清空,否则第一次循环sheet1时直接清空了上传列表,第二次循环sheet2就没数据了
} catch (e) {
console.log(e);
return false;
}
};
// 如果为原生 input 则应是 files[0]
fileReader.readAsBinaryString(file.raw);
},
複数シートの読み取りレンダリング