vue2文件下载和合计表格

news2025/7/13 1:31:40

vue2文件数据不多可以直接下载不需要后端的时候

1.首先,确保你已经安装了 docxfile-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);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1819793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

舵机堵转的危害与简单解决方式

舵机的堵转保护是一种安全特性&#xff0c;用于防止舵机在遇到阻力无法正常旋转时受到损害。当舵机尝试移动到某个位置但因为外部阻力&#xff08;如卡住或碰撞&#xff09;而无法完成动作时&#xff0c;它会持续施加力直至达到其最大扭矩。如果没有堵转保护&#xff0c;这种情…

OpenCV学习(4.14) 基于分水岭算法的图像分割

1. 目标 在这一章当中&#xff0c; 我们将学习使用分水岭算法使用基于标记的图像分割我们将看到&#xff1a;cv.watershed() 2.理论 任何灰度图像都可以看作是地形表面&#xff0c;其中高强度表示峰和丘陵&#xff0c;而低强度表示山谷。您开始用不同颜色的水&#xff08;标…

什么是基于风险的漏洞管理RBVM,及其优势

文章目录 一、什么是漏洞管理二、什么是基于风险的漏洞管理RBVM三、RBVM的基本流程四、RBVM的特点和优势 一、什么是漏洞管理 安全漏洞是网络或网络资产的结构、功能或实现中的任何缺陷或弱点&#xff0c;黑客可以利用这些缺陷或弱点发起网络攻击&#xff0c;获得对系统或数据…

Vue前端ffmpeg压缩视频再上传(全网唯一公开真正实现)

1.Vue项目中安装插件ffmpeg 1.1 插件版本依赖配置 两个插件的版本 "ffmpeg/core": "^0.10.0", "ffmpeg/ffmpeg": "^0.10.1"package.json 和 package-lock.json 都加入如下ffmpeg的版本配置&#xff1a; 1.2 把ffmpeg安装到项目依…

飞腾派初体验(2)

水个字数&#xff0c;混个推广分&#xff0c;另外几个点还是想吐槽一下 - 1&#xff0c;上篇文章居然没有给开发板一个硬照&#xff0c;补上 - 飞腾派 自拍 2. 现在做镜像用Win32DiskImager的多吗&#xff1f;我记得当年都是dd命令搞定&#xff0c;玩树莓派的应该记得这个命令…

离散化——Acwing.802区间和

离散化 定义 离散化可以简单理解为将连续的数值或数据转换为离散的、有限个不同的值或类别。离散化就是将一个可能具有无限多个取值或在一个较大范围内连续取值的变量&#xff0c;通过某种规则或方法&#xff0c;划分成若干个离散的区间或类别&#xff0c;并将原始数据映射到…

【课程总结】Day8(下):计算机视觉基础入门

前言 数据结构 在人工智能领域&#xff0c;机器可以处理的数据类型如上图&#xff0c;大约可以分为以上类别。其中较为常用的数据类别有&#xff1a; 表格类数据 数据特点&#xff1a; 成行成列&#xff1a;一行一个样本&#xff0c;一列一个特征特征之间相互独立&#xff0…

最实用的AI软件开发工具CodeFlying测评

就在上个月&#xff0c;OpenAI宣布GPT-4o支持免费试用&#xff0c;调用API价格降到5美元/百万token。 谷歌在得到消息后立马将Gemini 1.5 的价格下降到0.35美元/百万token。 Anthropic的API价格&#xff0c;直接干到了0.25美元/百万token。 国外尚且如此&#xff0c;那么国内…

科技赋能,避震婴儿车或成为行业硬通货

全球知识经济发展发展到今天&#xff0c;消费者对于品质、服务、体验的要求越来越高&#xff0c;与之对应的产品也就越来越科技化、智能化、个性化&#xff0c;品牌化和差异化逐步成为产品的竞争核心。 婴儿推车作为关系婴幼儿出行安全的支柱性产业之一&#xff0c;从车架结构…

分享一份 .NET Core 简单的自带日志系统配置,平时做一些测试或个人代码研究,用它就可以了

前言 实际上&#xff0c;.NET Core 内部也内置了一套日志系统&#xff0c;它是一个轻量级的日志框架&#xff0c;用于记录应用程序的日志信息。 它提供了 ILogger 接口和 ILoggerProvider 接口&#xff0c;以及一组内置的日志提供程序&#xff08;如 Console、Debug、EventSo…

STM32-17-DAC

STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 STM32-12-OLED模块 STM32-13-MPU STM32-14-FSMC_LCD STM32-15-DMA…

uni-ui:基于uni-app的全端兼容高性能UI框架

一、引言 在移动应用开发领域&#xff0c;跨平台框架因其能够降低开发成本、提高开发效率而备受开发者青睐。其中&#xff0c;uni-app作为一个使用Vue.js开发所有前端应用的框架&#xff0c;不仅支持编译到iOS、Android、H5、以及各种小程序等多个平台&#xff0c;还因其丰富的…

实现开发板三盏灯点亮熄灭

实现开发板三盏灯点亮熄灭 typedef struct {volatile unsigned int MODER; // 0x00volatile unsigned int OTYPER; // 0x04volatile unsigned int OSPEEDR; // 0x08volatile unsigned int PUPDR; // 0x0Cvolatile unsigned int IDR; // 0x10volatile unsigned int OD…

无线网络与物联网技术[1]之近距离无线通信技术

无线网络与物联网技术 近距离无线通信技术WIFIWi-Fi的协议标准Wi-Fi的信道Wi-Fi技术的术语Wi-Fi的组网技术Ad-hoc模式无线接入点-APAP&#xff1a;FAT AP vs FIT AP Wi-Fi的特点与应用Wi-Fi的安全技术 Bluetooth蓝牙技术概论蓝牙的技术协议蓝牙的组网技术微微网piconet(了解)散…

C#聊天室①

聊天室服务器&#xff1a; 创建项目 桌面不需要使用控件 Program.cs internal class Program {static TcpListener server;[STAThread]static void Main(){Program p new Program(); p.start();}void start(){server new TcpListener(IPAddress.Parse(GetIP()), 33…

58.WEB渗透测试-信息收集- 端口、目录扫描、源码泄露(6)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;57.WEB渗透测试-信息收集- 端口、目录扫描、源码泄露&#xff08;5&#xff09;-CSDN博客…

模拟笔试 - 卡码网周赛第二十一期(23年美团笔试真题)

第一题&#xff1a;小美的排列询问 解题思路: 简单题&#xff0c;一次遍历数组&#xff0c;判断 是否有和x、y相等并且相连 即可。 可优化逻辑&#xff1a;因为x和y是后输入的&#xff0c;必须存储整个数组&#xff0c;但是上面说了 **排列是指一个长度为n的数组&#xff0…

学习笔记——网络管理与运维——概述(网络管理)

二、概述 1、什么是网络管理&#xff1f; 网络管理是通过对网络中设备的管理&#xff0c;保证设备工作正常&#xff0c;使通信网络正常地运行&#xff0c;以提供高效、可靠和安全的通信服务&#xff0c;是通信网络生命周期中的重要一环。 2、网络管理分类 网络管理(Network …

C++ 24 之 拷贝构造函数

c24拷贝构造函数.cpp #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std;class Person3 { private:int p_age; public:// 构造函数分类&#xff1a;// 按参数分类&#xff1a;1、有参 2、无参// 按类型分类:普通、拷贝&#xff08;复制&…

Charles代理https接口到本地

一、操作手册 1、安装工具 1.1、安装代理软件Charles 软件下载地址&#xff1a;Download a Free Trial of Charles • Charles Web Debugging Proxy 1.2、安装https代理插件&#xff1a;&#xff08;有问题自行百度解决&#xff09; 2、配置策略 以下以https接口为例&…