vue2文件数据不多可以直接下载不需要后端的时候
1.首先,确保你已经安装了 docx
和 file-saver
库
npm install file-saver
npm install docx file-saver
2.全部代码如下
<template>
<a-modal
title="详情"
width="80%"
v-model="visible"
:confirmLoading="confirmLoading"
>
<a-descriptions title="" bordered>
<a-descriptions-item label="出租方">{{ form.rentOrg }}</a-descriptions-item>
<a-descriptions-item label="承租方">{{ form.lesseeOrg }}</a-descriptions-item>
<a-descriptions-item label="统一社会信息代码">{{ form.socialCode }}</a-descriptions-item>
<a-descriptions-item label="合同时间">{{ form.startDate }}-{{ form.endDate }}</a-descriptions-item>
<a-descriptions-item label="合同编号">{{ form.contractNo }}</a-descriptions-item>
<a-descriptions-item label="合同名称">{{ form.contractName }}</a-descriptions-item>
</a-descriptions>
<div class="table-operator">
<a-button type="primary" @click="generateDocx">下载缴费单</a-button>
</div>
<a-table
ref="table"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:rowSelection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
bordered
>
<span slot="action" slot-scope="text, record">
<a v-if="record.payStatus == 1" @click="payment(record, false)">缴费</a>
<a v-else @click="payment(record, true)">详情</a>
</span>
</a-table>
<costDeatil ref="costDeatil" @getBillDetail="getBillDetail"></costDeatil>
<div slot="footer">
<a-button type="dashed" @click="visible = false">关闭</a-button>
</div>
</a-modal>
</template>
<script>
import costDeatil from "./components/costDeatil.vue";
import { getBillDetail } from "@/api/assetrentplan";
import { JeecgListMixin } from "@/mixins/JeecgListMixin";
import { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, WidthType } from "docx";
import { saveAs } from "file-saver";
export default {
components: { costDeatil },
mixins: [JeecgListMixin],
data() {
return {
visible: false,
confirmLoading: false,
columns: [
{
title: "费用周期",
dataIndex: "date",
align: "center",
customRender: (text, record) => `${record.startDate}-${record.endDate}`,
},
{
title: "租约到期日期",
dataIndex: "rentEndDate",
align: "center",
},
{
title: "应收金额(元)",
dataIndex: "shouldPayMoney",
align: "center",
},
{
title: "缴费状态",
dataIndex: "payStatus",
align: "center",
customRender: (text) => `${text == 1 ? "待缴费" : "已缴费"}`,
},
{
title: "实收金额",
dataIndex: "realPayMoney",
align: "center",
},
{
title: "实收日期",
dataIndex: "realPayDate",
align: "center",
},
{
title: "操作人",
dataIndex: "operatePersonName",
align: "center",
},
{
title: "操作日期",
dataIndex: "operateDate",
align: "center",
},
{
title: "操作",
width: "150px",
scopedSlots: { customRender: "action" },
align: "center",
},
],
selectedRowKeys: [],
disableMixinCreated: true,
form: {},
pagination: {
current: 1,
pageSize: 10,
total: 0,
showTotal: (total) => `共 ${total} 条数据`,
},
};
},
methods: {
payment(record, disabled) {
this.$refs.costDeatil.clickShowModal(record, disabled);
},
onSelectChange(row) {
this.selectedRowKeys = row;
},
getBillDetail() {
this.loading = true;
getBillDetail(this.form.id)
.then((res) => {
this.loading = false;
if (res.code == 0) {
this.form = res.data;
this.dataSource = res.data.assetRentBillList;
}
})
.catch((err) => {
this.loading = false;
});
},
clickShowModal(record) {
this.visible = true;
this.dataSource = [];
this.form = record;
this.getBillDetail();
},
generateDocx() {
const doc = new Document({
sections: [
{
children: [
new Paragraph({
children: [
new TextRun({
text: "缴费单详情",
bold: true,
size: 24,
}),
],
}),
new Table({
rows: [
new TableRow({
children: [
new TableCell({
children: [new Paragraph("费用周期")],
width: { size: 10, type: WidthType.PERCENTAGE },
}),
new TableCell({
children: [new Paragraph("租约到期日期")],
width: { size: 10, type: WidthType.PERCENTAGE },
}),
new TableCell({
children: [new Paragraph("应收金额(元)")],
width: { size: 10, type: WidthType.PERCENTAGE },
}),
new TableCell({
children: [new Paragraph("缴费状态")],
width: { size: 10, type: WidthType.PERCENTAGE },
}),
new TableCell({
children: [new Paragraph("实收金额")],
width: { size: 10, type: WidthType.PERCENTAGE },
}),
new TableCell({
children: [new Paragraph("实收日期")],
width: { size: 10, type: WidthType.PERCENTAGE },
}),
new TableCell({
children: [new Paragraph("操作人")],
width: { size: 10, type: WidthType.PERCENTAGE },
}),
new TableCell({
children: [new Paragraph("操作日期")],
width: { size: 10, type: WidthType.PERCENTAGE },
}),
],
}),
//在 docx 库中,确保你处理数据时避免出现空值或未定义的值是很重要的。你可以通过在构建文档时检查并处理这些空值来避免这种错误。
...this.dataSource.map((item) =>
new TableRow({
children: [
new TableCell({
children: [new Paragraph(`${item.startDate || ''}-${item.endDate || ''}`)],
}),
new TableCell({
children: [new Paragraph(item.rentEndDate || '')],
}),
new TableCell({
children: [new Paragraph(item.shouldPayMoney != null ? item.shouldPayMoney.toString() : '')],
}),
new TableCell({
children: [new Paragraph(item.payStatus == 1 ? "待缴费" : "已缴费")],
}),
new TableCell({
children: [new Paragraph(item.realPayMoney != null ? item.realPayMoney.toString() : '')],
}),
new TableCell({
children: [new Paragraph(item.realPayDate || '')],
}),
new TableCell({
children: [new Paragraph(item.operatePersonName || '')],
}),
new TableCell({
children: [new Paragraph(item.operateDate || '')],
}),
],
})
),
],
}),
],
},
],
});
Packer.toBlob(doc).then((blob) => {
saveAs(blob, "缴费单详情.docx");
});
},
},
};
</script>
vue2数据很多的时候需要后端
<a-button type="primary" style="margin-left: 8px" @click="getExport"
>下载导入模板</a-button
>
import { downloadFile } from "@/api/manage";
api/manage代码如下
// import { axios } from '@/utils/request'
import axios from "@/utils/axios";
import signMd5Utils from "@/utils/encryption/signMd5Utils";
const api = {
user: "/mock/api/user",
role: "/mock/api/role",
service: "/mock/api/service",
permission: "/mock/api/permission",
permissionNoPager: "/mock/api/permission/no-pager",
};
export default api;
//post
export function postAction(url, parameter) {
let sign = signMd5Utils.getSign(url, parameter);
//将签名和时间戳,添加在请求接口 Header
let signHeader = {
"X-Sign": sign,
"X-TIMESTAMP": signMd5Utils.getDateTimeToString(),
};
return axios({
url: url,
method: "post",
data: parameter,
headers: signHeader,
});
}
//post method= {post | put}
export function httpAction(url, parameter, method) {
let sign = signMd5Utils.getSign(url, parameter);
//将签名和时间戳,添加在请求接口 Header
let signHeader = {
"X-Sign": sign,
"X-TIMESTAMP": signMd5Utils.getDateTimeToString(),
};
return axios({
url: url,
method: method,
data: parameter,
headers: signHeader,
});
}
//put
export function putAction(url, parameter) {
return axios({
url: url,
method: "put",
data: parameter,
});
}
//get
export function getAction(url, parameter) {
let sign = signMd5Utils.getSign(url, parameter);
//将签名和时间戳,添加在请求接口 Header
let signHeader = {
"X-Sign": sign,
"X-TIMESTAMP": signMd5Utils.getDateTimeToString(),
};
return axios({
url: url,
method: "get",
params: parameter,
headers: signHeader,
});
}
//deleteAction
export function deleteAction(url, parameter) {
return axios({
url: url,
method: "delete",
params: parameter,
});
}
export function getUserList(parameter) {
return axios({
url: api.user,
method: "get",
params: parameter,
});
}
export function getRoleList(parameter) {
return axios({
url: api.role,
method: "get",
params: parameter,
});
}
export function getServiceList(parameter) {
return axios({
url: api.service,
method: "get",
params: parameter,
});
}
export function getPermissions(parameter) {
return axios({
url: api.permissionNoPager,
method: "get",
params: parameter,
});
}
// id == 0 add post
// id != 0 update put
export function saveService(parameter) {
return axios({
url: api.service,
method: parameter.id == 0 ? "post" : "put",
data: parameter,
});
}
/**
* 下载文件 用于excel导出
* @param url
* @param parameter
* @returns {*}
*/
export function downFile(url, parameter, method) {
return axios({
url: url,
params: parameter,
method: method ? method : "get",
responseType: "blob",
});
}
/**
* 下载文件
* @param url 文件路径
* @param fileName 文件名
* @param parameter
* @returns {*}
*/
export function downloadFile(url, fileName, parameter,method) {
return downFile(url, parameter,method).then((data) => {
// if (!data || data.size === 0) {
// Vue.prototype['$message'].warning('文件下载失败')
// return
// }
if (typeof window.navigator.msSaveBlob !== "undefined") {
window.navigator.msSaveBlob(new Blob([data]), fileName);
} else {
let url = window.URL.createObjectURL(new Blob([data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
});
}
/**
* 文件上传 用于富文本上传图片
* @param url
* @param parameter
* @returns {*}
*/
export function uploadAction(url, parameter) {
return axios({
url: url,
data: parameter,
method: "post",
headers: {
"Content-Type": "multipart/form-data", // 文件上传
},
});
}
/**
* 获取文件服务访问路径
* @param avatar
* @param subStr
* @returns {*}
*/
export function getFileAccessHttpUrl(avatar, subStr) {
if (!subStr) subStr = "http";
try {
if (avatar && avatar.startsWith(subStr)) {
return avatar;
} else {
if (avatar && avatar.length > 0 && avatar.indexOf("[") == -1) {
return window._CONFIG["staticDomainURL"] + "/" + avatar;
}
}
} catch (err) {
return;
}
}
//导出模板
getExport() {
downloadFile(
"/asset/entryrecord/exportTemplateXls",
"财务信息模板.xlsx",
{},
"post"
);
},
合计
效果如图
代码
columns: [
{
title: "序号",
customRender: (text, record, index) => {
if (record.isTotalRow) {
return {
children: "合计",
attrs: { colSpan: 3 },
};
}
return index + 1;
},
width: 70,
align: "center",
},
{
title: "企业名称",
align: "center",
dataIndex: "companyName",
width: 150,
customRender: (text, record, index) => {
if (record.isTotalRow) {
return {
children: null,
attrs: { colSpan: 0 },
};
}
return text;
},
},
{
title: "转让资产名称",
align: "center",
dataIndex: "assetName",
width: 150,
customRender: (text, record, index) => {
if (record.isTotalRow) {
return {
children: null,
attrs: { colSpan: 0 },
};
}
return text;
},
},
{
title: "账面净值(元)",
align: "center",
dataIndex: "bookMoney",
width: 150,
},
{
title: "转让方式",
align: "center",
dataIndex: "transferWay",
width: 150,
customRender: (text, record, index) => {
switch (Number.parseInt(text)) {
case 1:
return "公开转让";
case 2:
return "协议转让";
default:
return "/";
}
},
},
{
title: "转让行为最终审批单位",
align: "center",
dataIndex: "transferFinalOrg",
width: 150,
customRender: (text, record, index) => {
switch (Number.parseInt(text)) {
case 1:
return "市政府";
case 2:
return "左海集团";
case 3:
return "二级企业";
default:
return "/";
}
},
},
{
title: "受让方名称",
align: "center",
dataIndex: "receiveName",
width: 150,
},
{
title: "受让方性质",
align: "center",
dataIndex: "receiveType",
width: 150,
customRender: (text, record, index) => {
switch (Number.parseInt(text)) {
case 1:
return "个人";
case 2:
return "私有企业";
case 3:
return "国有全资企业";
case 4:
return "国有控股企业";
case 5:
return "国有实际控制企业";
case 6:
return "国有参股企业";
default:
return "其他";
}
},
},
{
title: "评估价值(元)",
align: "center",
dataIndex: "evaluateMoney",
width: 150,
},
{
title: "转让底价(元)",
align: "center",
dataIndex: "transferMinPrice",
width: 150,
},
{
title: "成交金额(元)",
align: "center",
dataIndex: "dealMoney",
width: 150,
},
{
title: "溢价(元)",
align: "center",
dataIndex: "moreMoney",
width: 150,
},
{
title: "转让合同签订日期",
align: "center",
dataIndex: "signDate",
width: 150,
},
{
title: "备注",
align: "center",
dataIndex: "remark",
width: 150,
},
],
assetTransferAllCount() {
this.loading = true;
const meta = { companyName: this.queryParam.companyName };
// console.log("this.queryParam", this.queryParam);
assetTransferAllCount(meta)
.then((res) => {
this.loading = false;
if (res.code == 0) {
console.log("res", res);
this.dataSource = res.data.list;
// console.log(" this.dataSource", this.dataSource);
// 使用解构赋值简化对象创建过程
const {
bookMoney,
transferWay,
transferFinalOrg,
receiveName,
receiveType,
evaluateMoney,
transferMinPrice,
dealMoney,
moreMoney,
signDate,
remark,
} = res.data;
const obj = {
isTotalRow: true,
bookMoney,
transferWay: "/",
transferFinalOrg: "/",
receiveName: "/",
receiveType: "/",
evaluateMoney,
transferMinPrice,
dealMoney,
moreMoney,
signDate: "/",
remark,
};
this.dataSource.push(obj);
// console.log(" this.dataSource22", this.dataSource);
}
})
.catch((error) => {
this.loading = false;
console.error("Error fetching data:", error);
});
},
重点是
this.dataSource.push(obj);