vue導(dǎo)出excel和echart圖形分別在不同工作表的實現(xiàn)方法
背景
實現(xiàn)一鍵導(dǎo)出excel并且區(qū)分圖表和表格為不同的sheet工作表
最終效果為

代碼實現(xiàn)
功能實現(xiàn)
<script lang="ts">
import * as echarts from 'echarts';
import ExcelJS from 'exceljs';
import { saveAs } from 'file-saver';
import {getAsyncTempCurrentData} from '../../../api/fenxi'
import { toRefs } from 'vue'
import FileSaver from "file-saver";
import * as XLSX from 'xlsx'
import { ref, reactive, onMounted ,getCurrentInstance,nextTick } from 'vue'
export default {
data() {
const state = reactive({
tableData: [] as any, // 表格數(shù)據(jù)
dialog: false, // 模態(tài)框顯示、隱藏
name: '' // 自定義文件名
})
// const tableData = ref();
const { tableData, dialog, name } = toRefs(state)
return {
chart: null,
tableData
};
},
mounted() {
this.chart = echarts.init(this.$refs.chart);
this.fetchData();
},
methods: {
fetchData() {
getAsyncTempCurrentData().then((response) => {
console.log(response);
this.tableData = response.data;
const years = response.data.map((item) => item.year + '年' + item.month + '月');
const charges = response.data.map((item) => item.charge);
const discharges = response.data.map((item) => item.discharge);
const temps = response.data.map((item) => item.temp);
const option = {
textStyle:{
color:"gray"},
tooltip: {
trigger: 'axis',
axisPointer: { // 坐標(biāo)軸指示器,坐標(biāo)軸觸發(fā)有效
type: 'shadow' // 默認(rèn)為直線,可選為:'line' | 'shadow'
},
show: true,
},
grid: {
left: '2%',
right: '4%',
bottom: '14%',
top:'16%',
containLabel: false
},
legend: {
data: ['充電量', '放電量', '溫度'],
right: 10,
top:12,
textStyle: {
color: "#fff"
},
// itemGap: 35
},
xAxis: {
type: 'category',
data: years,
axisLine: {
lineStyle: {
color: 'white'
}
},
axisLabel: {
// interval: 0,
// rotate: 40,
textStyle: {
fontFamily: 'Microsoft YaHei'
}
},
},
yAxis: [
{
type: 'value',
scale: false,
min: 0,
axisLine: {
show: false,
lineStyle: {
color: 'white'
}
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255,255,255,0.3)'
}
},
axisLabel: {}
},
{
type: 'value',
scale: true,
axisLine: {
show: false,
lineStyle: {
color: 'gray'
}
},
splitLine: {
show: true,
lineStyle: {
color: 'gray'
}
},
axisLabel: {}
}
],
series: [{
name: '充電量',
type: 'bar',
barWidth: '15%',
yAxisIndex: 0,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#fccb05'
}, {
offset: 1,
color: '#f5804d'
}]),
barBorderRadius: 12,
},
},
data: charges,
},
{
name: '放電量',
type: 'bar',
barWidth: '15%',
yAxisIndex: 0,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#8bd46e'
}, {
offset: 1,
color: '#09bcb7'
}]),
barBorderRadius: 11,
}
},
data: discharges
},
{
name: '溫度',
type: 'line',
yAxisIndex: 1,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#248ff7'
}, {
offset: 1,
color: '#6851f1'
}]),
barBorderRadius: 11,
}
},
data: temps
}]
};
this.chart.setOption(option);
});
},
exportExcel() {
const workbook = new ExcelJS.Workbook();
const tableData = Array.from(document.querySelectorAll('#el-table tbody tr')).map(row => {
return Array.from(row.querySelectorAll('td')).map(cell => cell.innerText);
});
const header = ['序號', '年份', '月份', '充電量', '放電量', '溫度']; // 表頭數(shù)據(jù)
tableData.unshift(header);
const columnIndexToRemove = 0;
// 遍歷 elTable 數(shù)組,將每一行的第一列數(shù)據(jù)刪除
tableData.forEach(row => {
row.splice(columnIndexToRemove, 1);
});
const worksheet = workbook.addWorksheet('數(shù)據(jù)圖形');
const worksheet2 = workbook.addWorksheet('數(shù)據(jù)表格');
const chart = echarts.getInstanceByDom(this.$refs.chart);
const base64Image = chart.getDataURL({
pixelRatio: 2,
backgroundColor: '#fff',
});
let image = workbook.addImage({
base64: base64Image,
extension: 'png',
});
worksheet.addImage(image, 'A1:Z30');
worksheet2.addRows(tableData);
workbook.xlsx.writeBuffer().then(function (buffer) {
saveAs.saveAs(
new Blob([buffer], {
type: 'application/octet-stream',
}),
'xchart.xlsx'
);
});
},
},
};
</script>
<template>
<div>
<div ref="chart" id="lineChart" style="height: 400px; width: 1000px"></div>
<el-button @click="exportExcel">導(dǎo)出圖表</el-button>
<el-table :data="tableData" style="width: 100%" id="el-table" border ref="tableRef" v-show="true">
<el-table-column type="selection" width="50" align="center" />
<el-table-column prop="year" label="年份"></el-table-column>
<el-table-column prop="month" label="月份"></el-table-column>
<el-table-column prop="charge" label="充電量"></el-table-column>
<el-table-column prop="discharge" label="放電量"></el-table-column>
<el-table-column prop="temp" label="溫度"></el-table-column>
</el-table>
</div>
</template>
## 模態(tài)框點擊以及自定義文件名
添加模態(tài)框組件
<el-dialog v-model="dialog" title="表格導(dǎo)出" width="30%" @close="closeDialog">
<el-input v-model="name" placeholder="請輸入導(dǎo)出文件的文件名"></el-input>
<el-alert title="默認(rèn)文件名為(站點名+數(shù)據(jù)文件)" type="info" :closable="false" style="margin-top: 10px;" />
<template #footer>
<span class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="exportExcel">確定</el-button>
</span>
</template>
</el-dialog>
綁定開閉狀態(tài),在按鈕上修改觸發(fā)方法為開啟模態(tài)框
<el-button @click="openExportDialog">導(dǎo)出圖表</el-button> <!-- 導(dǎo)出按鈕 -->
對應(yīng)的方法是
openExportDialog() {
this.dialog = true; // 打開模態(tài)框
},
closeDialog() {
this.dialog = false; // 關(guān)閉模態(tài)框
},
然后修改相應(yīng)的狀態(tài)
全部代碼
<script lang="ts">
import * as echarts from 'echarts';
import ExcelJS from 'exceljs';
import { saveAs } from 'file-saver';
import {getAsyncTempCurrentData} from '../../../api/fenxi'
import { toRefs } from 'vue'
import FileSaver from "file-saver";
import * as XLSX from 'xlsx'
import { ref, reactive, onMounted ,nextTick } from 'vue'
import { selectedStoreHook,useselectedStore } from "../../../store/modules/selected";
const store = useselectedStore();
const state = reactive({
tableData: [] as any, // 表格數(shù)據(jù)
dialog: false, // 模態(tài)框顯示、隱藏
name: '' // 自定義文件名
})
let filename = '';
const { tableData, dialog, name } = toRefs(state)
export default {
data() {
const state = reactive({
tableData: [] as any, // 表格數(shù)據(jù)
dialog: false, // 模態(tài)框顯示、隱藏
name: '' // 自定義文件名,
})
return {
chart: null,
tableData,
dialog,
name,
};
},
mounted() {
this.chart = echarts.init(this.$refs.chart);
this.fetchData();
},
methods: {
fetchData() {
getAsyncTempCurrentData().then((response) => {
console.log(response);
this.tableData = response.data;
const years = response.data.map((item) => item.year + '年' + item.month + '月');
const charges = response.data.map((item) => item.charge);
const discharges = response.data.map((item) => item.discharge);
const temps = response.data.map((item) => item.temp);
const option = {
textStyle:{
color:"gray"},
tooltip: {
trigger: 'axis',
axisPointer: { // 坐標(biāo)軸指示器,坐標(biāo)軸觸發(fā)有效
type: 'shadow' // 默認(rèn)為直線,可選為:'line' | 'shadow'
},
show: true,
},
grid: {
left: '2%',
right: '4%',
bottom: '14%',
top:'16%',
containLabel: false
},
legend: {
data: ['充電量', '放電量', '溫度'],
right: 10,
top:12,
textStyle: {
color: "#fff"
},
// itemGap: 35
},
xAxis: {
type: 'category',
data: years,
axisLine: {
lineStyle: {
color: 'white'
}
},
axisLabel: {
// interval: 0,
// rotate: 40,
textStyle: {
fontFamily: 'Microsoft YaHei'
}
},
},
yAxis: [
{
type: 'value',
scale: false,
min: 0,
axisLine: {
show: false,
lineStyle: {
color: 'white'
}
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(255,255,255,0.3)'
}
},
axisLabel: {}
},
{
type: 'value',
scale: true,
axisLine: {
show: false,
lineStyle: {
color: 'gray'
}
},
splitLine: {
show: true,
lineStyle: {
color: 'gray'
}
},
axisLabel: {}
}
],
series: [{
name: '充電量',
type: 'bar',
barWidth: '15%',
yAxisIndex: 0,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#fccb05'
}, {
offset: 1,
color: '#f5804d'
}]),
barBorderRadius: 12,
},
},
data: charges,
},
{
name: '放電量',
type: 'bar',
barWidth: '15%',
yAxisIndex: 0,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#8bd46e'
}, {
offset: 1,
color: '#09bcb7'
}]),
barBorderRadius: 11,
}
},
data: discharges
},
{
name: '溫度',
type: 'line',
yAxisIndex: 1,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#248ff7'
}, {
offset: 1,
color: '#6851f1'
}]),
barBorderRadius: 11,
}
},
data: temps
}]
};
this.chart.setOption(option);
});
},
openExportDialog() {
this.dialog = true; // 打開模態(tài)框
},
closeDialog() {
this.dialog = false; // 關(guān)閉模態(tài)框
},
close() {
// 模態(tài)框取消,重新獲取數(shù)據(jù)
this.fetchData();
},
exportExcel() {
if (state.name === '') {
// 默認(rèn)導(dǎo)出文件名
filename = '站點' + store.siteid + '數(shù)據(jù)文件';
} else {
filename = state.name ;
}
const workbook = new ExcelJS.Workbook();
const tableData = Array.from(document.querySelectorAll('#el-table tbody tr')).map(row => {
return Array.from(row.querySelectorAll('td')).map(cell => cell.innerText);
});
const header = ['序號', '年份', '月份', '充電量', '放電量', '溫度']; // 表頭數(shù)據(jù)
tableData.unshift(header);
const columnIndexToRemove = 0;
// 遍歷 elTable 數(shù)組,將每一行的第一列數(shù)據(jù)刪除
tableData.forEach(row => {
row.splice(columnIndexToRemove, 1);
});
const worksheet = workbook.addWorksheet('數(shù)據(jù)圖形');
const worksheet2 = workbook.addWorksheet('數(shù)據(jù)表格');
const chart = echarts.getInstanceByDom(this.$refs.chart);
const base64Image = chart.getDataURL({
pixelRatio: 2,
backgroundColor: '#fff',
});
let image = workbook.addImage({
base64: base64Image,
extension: 'png',
});
worksheet.addImage(image, 'A1:Z30');
worksheet2.addRows(tableData);
workbook.xlsx.writeBuffer().then(function (buffer) {
saveAs.saveAs(
new Blob([buffer], {
type: 'application/octet-stream',
}),
filename+'.xlsx'
);
});
},//
save() {
nextTick(function () {
let filename = '';
if (state.name === '') {
// 默認(rèn)導(dǎo)出文件名
filename = '站點' + store.siteid + '數(shù)據(jù)文件.xlsx';
} else {
filename = state.name += '.xlsx';
}
const header = ['序號', '年份', '月份', '充電量', '放電量', '溫度']; // 表頭數(shù)據(jù)
// 將表頭插入到 elTable 數(shù)組的開頭
// 創(chuàng)建工作簿
const workbook = XLSX.utils.book_new();
const xlsxParam = { raw: true }; // 轉(zhuǎn)化成Excel使用原始格式
// 獲取表格數(shù)據(jù)
const tableData = Array.from(document.querySelectorAll('#el-table tbody tr')).map(row => {
return Array.from(row.querySelectorAll('td')).map(cell => cell.innerText);
});
tableData.unshift(header);
const columnIndexToRemove = 0;
// 遍歷 elTable 數(shù)組,將每一行的第一列數(shù)據(jù)刪除
tableData.forEach(row => {
row.splice(columnIndexToRemove, 1);
});
// 創(chuàng)建工作表1
const sheet1 = XLSX.utils.aoa_to_sheet(tableData);
// 將工作表1添加到工作簿
XLSX.utils.book_append_sheet(workbook, sheet1, '表格');
// 將echarts圖表轉(zhuǎn)換為圖片
// 創(chuàng)建工作表2
const sheet2 = XLSX.utils.aoa_to_sheet([]);
const img = new Image();
img.src = 'http://localhost:4444/src/assets/admin.png';
// const chart = echarts.getInstanceByDom(this.$refs.chart) // 獲取圖表實例
// const base64Image = chart.getDataURL({
// pixelRatio: 2, // 導(dǎo)出圖片的分辨率比例,默認(rèn)為1,即圖片的分辨率為屏幕分辨率的一倍
// backgroundColor: '#fff' // 導(dǎo)出圖片的背景色
// })
// let image= workbook.addImage({ // 添加圖片
// base64: base64Image, // 圖片的base64編碼
// extension: 'png' // 圖片的擴展名
// });
// worksheet.addImage(image, 'A1:J20'); // 將圖片添加到工作表中
// workbook.xlsx.writeBuffer().then(function (buffer) { // 生成excel文件的二進(jìn)制數(shù)據(jù)
// saveAs.saveAs(new Blob([buffer], { // 生成Blob對象
// type: 'application/octet-stream' // 指定文件的MIME類型
// }), 'xchart.xlsx'); // 指定文件名
// });
XLSX.utils.book_append_sheet(workbook, sheet2, '圖表');
// 導(dǎo)出Excel文件
XLSX.writeFile(workbook, filename);
});
}
}
};
</script>
<template>
<div ref="export" >
<div ref="chart" id="lineChart" style="height: 400px; width: 1000px" v-show="false"></div>
<!-- <el-button @click="exportExcel">導(dǎo)出圖表</el-button>
<el-button type="primary" @click="exportExcel">導(dǎo)出</el-button>導(dǎo)出按鈕 -->
<el-button @click="openExportDialog">導(dǎo)出圖表</el-button> <!-- 導(dǎo)出按鈕 -->
<!-- 模態(tài)框 -->
<el-dialog v-model="dialog" title="表格導(dǎo)出" width="30%" @close="closeDialog">
<el-input v-model="name" placeholder="請輸入導(dǎo)出文件的文件名"></el-input>
<el-alert title="默認(rèn)文件名為(站點名+數(shù)據(jù)文件)" type="info" :closable="false" style="margin-top: 10px;" />
<template #footer>
<span class="dialog-footer">
<el-button @click="closeDialog">取消</el-button>
<el-button type="primary" @click="exportExcel">確定</el-button>
</span>
</template>
</el-dialog>
<el-table :data="tableData" style="width: 100%" id="el-table" border ref="tableRef" v-show="false">
<el-table-column type="selection" width="50" align="center" />
<el-table-column prop="year" label="年份"></el-table-column>
<el-table-column prop="month" label="月份"></el-table-column>
<el-table-column prop="charge" label="充電量"></el-table-column>
<el-table-column prop="discharge" label="放電量"></el-table-column>
<el-table-column prop="temp" label="溫度"></el-table-column>
</el-table>
</div>
</template>
以上就是vue導(dǎo)出excel和echart圖形分別在不同工作表的實現(xiàn)方法的詳細(xì)內(nèi)容,更多關(guān)于vue導(dǎo)出excel和echart在不同工作表的資料請關(guān)注腳本之家其它相關(guān)文章!
- vue3+echarts實現(xiàn)好看的圓角環(huán)形圖
- echarts設(shè)置tootip輪播切換展示(vue3搭配vue-echarts粘貼即用)
- 手把手教你Vue3?按需引入?Echarts的過程(收藏)
- vue使用echarts實現(xiàn)柱狀圖動態(tài)排序效果
- vue2.0如何實現(xiàn)echarts餅圖(pie)效果展示
- vue中如何使用echarts動態(tài)渲染數(shù)據(jù)
- vue使用echarts實現(xiàn)動態(tài)數(shù)據(jù)的示例詳解
- Vuex進(jìn)行Echarts數(shù)據(jù)頁面初始化后如何更新dom
- vue+echarts圖表的基本使用步驟總結(jié)
- 在Vue中使用Echarts+封裝
- 使用vue3+ts打開echarts的正確方式
- vue3中使用Vchart的示例代碼
相關(guān)文章
Vue監(jiān)聽Enter鍵的方法總結(jié)與區(qū)別
這篇文章主要給大家介紹了關(guān)于Vue監(jiān)聽Enter鍵的方法與區(qū)別的相關(guān)資料,在Vue中我們可以通過監(jiān)聽鍵盤事件來實現(xiàn)回車鍵切換焦點的功能,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
vue頁面設(shè)置滾動失敗的完美解決方案(scrollTop一直為0)
這篇文章主要介紹了vue頁面設(shè)置滾動失敗的解決方案(scrollTop一直為0),本文通過場景分析實例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05
Vue的v-model的幾種修飾符.lazy,.number和.trim的用法說明
這篇文章主要介紹了Vue的v-model的幾種修飾符.lazy,.number和.trim的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
關(guān)于vue路由緩存清除在main.js中的設(shè)置
今天小編就為大家分享一篇關(guān)于vue路由緩存清除在main.js中的設(shè)置,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
Vue組件內(nèi)部實現(xiàn)一個雙向數(shù)據(jù)綁定的實例代碼
這篇文章主要介紹了Vue組件內(nèi)部實現(xiàn)一個雙向數(shù)據(jù)綁定的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04
vue3數(shù)據(jù)監(jiān)聽watch/watchEffect的示例代碼
我們都知道監(jiān)聽器的作用是在每次響應(yīng)式狀態(tài)發(fā)生變化時觸發(fā),在組合式?API?中,我們可以使用?watch()函數(shù)和watchEffect()函數(shù),下面我們來看下vue3如何進(jìn)行數(shù)據(jù)監(jiān)聽watch/watchEffect,感興趣的朋友一起看看吧2023-02-02

