vue3 pdf、word等文件下载

效果:

html 复制代码
      <div class="byLawBox">
        <div class="titleBox">规章制度公示</div>
        <div class="contentBox">
          <TableList
            :loading="byLawloading"
            ref="byLawtablistRef"
            :hasImport="false"
            :hasExport="false"
            @getData="byLawgetData"
            :columns="byLawcolumns"
            :showHeader="false"
            :MaxResultCount="10"
            :ischange="false"
          >
            <template #customtable="{ column, record }">
              <template v-if="column.key === 'icon'">
                <file-word-outlined
                  style="color: #1683ff"
                  v-if="
                    findFileType(record.FilePath[0]?.DisPlayName) == '.doc' ||
                    findFileType(record.FilePath[0]?.DisPlayName) == '.docx'
                  " />
                <file-ppt-outlined
                  style="color: #f57b11"
                  v-if="
                    findFileType(record.FilePath[0]?.DisPlayName) == '.ppt' ||
                    findFileType(record.FilePath[0]?.DisPlayName) == '.pptx'
                  " />
                <file-excel-outlined
                  style="color: #15c34f"
                  v-if="
                    findFileType(record.FilePath[0]?.DisPlayName) == '.xlsx' ||
                    findFileType(record.FilePath[0]?.DisPlayName) == '.xLs'
                  " />
                <file-pdf-outlined
                  style="color: #e83c35"
                  v-if="
                    findFileType(record.FilePath[0]?.DisPlayName) == '.pdf'
                  "
              /></template>
            </template>
            <template #operation="{ column, record }">
              <a @click="preview(record)"> 预览</a>
              <a-divider type="vertical" />
              <a @click="downLoadEvent(record)"> 下载</a>
            </template></TableList
          >
        </div>
      </div>
javascript 复制代码
const downLoadEvent = (param2) => {
  //下载操作
  if (
    Array.isArray(param2.FilePath) &&
    param2?.FilePath?.length &&
    param2?.FilePath[0]?.FileId
  ) {
    axios
      .get(
        window.defaultconfig.fileUrl +
          "/api/FileManage/Download" +
          `?Id=${param2.FilePath[0].FileId}`,
        { responseType: "arraybuffer" }
      )
      .then((res) => {
        const blob = new Blob([res.data], { type: "application/vnd.ms-excel" });
        const objectUrl = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.download = param2.FilePath[0].DisPlayName;
        a.href = objectUrl;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
      })
      .catch((error) => {
        message.error("系统异常,请联系管理员");
      });
  } else {
    message.error("文件不存在,无法下载");
  }
};
javascript 复制代码
const byLawcolumns = [
  {
    title: "图标",
    dataIndex: "icon",
    key: "icon",
    align: "right",
    width: 20,
  },
  {
    title: "文件名",
    dataIndex: "FilePath",
    ellipsis: true,
    key: "FilePath",
    align: "left",
    customRender: ({ text }) => text[0].DisPlayName,
  },
  {
    title: "操作",
    dataIndex: "operation",
    key: "operation",
    align: "right",
    width: 100,
  },
];

table组件

html 复制代码
<template>
  <div class="tableBox">
    <div class="btn-add">
      <a-space>
        <a-upload
          v-model:file-list="fileList"
          v-if="hasImport"
          name="file"
          accept=".xls,.xlsx"
          action=""
          :headers="headers"
          @change="handleChange"
        >
          <a-button type="primary"> 导入 </a-button>
        </a-upload>
        <a-button type="primary" v-if="hasExport" @click="handleAllExport"
          >导出全部</a-button
        >
        <a-button type="primary" v-if="allDel">全部删除</a-button>
        <a-button
          :disabled="dataSource.length === 0 || flagselectedRowKeys"
          v-if="rowSelection"
          @click="delEvent(selecrowdata, 'many')"
          >批量删除</a-button
        >
        <a-button
          :disabled="dataSource.length === 0 || flagselectedRowKeys"
          v-if="rowSelectionEdit"
          @click="manyEditEvent(selecrowdata, 'many')"
          >批量修改</a-button
        >
        <a-button
          :disabled="dataSource.length === 0 || flagselectedRowKeys"
          v-if="markread"
          @click="handleFlagRead(selecrowdata, 'hasread')"
          >标记已读</a-button
        >
        <a-button
          type="primary"
          v-if="operatingButton?.addbtn"
          @click="editEvent('add')"
          >{{ addbtnName ? addbtnName : "添加" }}</a-button
        >
        <a-button
        :disabled="dataSource.length === 0"
          type="primary"
          v-if="operatingButton?.export"
          @click="exportEvent('export')"
          >{{ "新建导出" }}</a-button
        >
        <a-button
          type="primary"
          v-if="operatingButton?.exportRecord"
          @click="exportEvent('exportRecord')"
          >{{ "导出记录" }}</a-button
        >
        <a-button type="primary" v-if="hasgoback" @click="handlegoback"
          >返回</a-button
        >
      </a-space>
    </div>
    <a-table
      :rowKey="row => row.id?row.id:row.Id"
      :showHeader="showHeader"
      :dataSource="dataSource"
      :columns="columns"
      :loading="loading"
      :scroll="{ x: tableOtherobj.scroll }"
      :expandIconColumnIndex="expandIconSet.expandIconColumnIndex"
      :expandIconAsCell="expandIconSet.expandIconAsCell"
      @expand="handleexpand"
      @expandedRowsChange="expandedRowsChange"
      :row-selection="
        rowSelection || markread || rowSelection2||rowSelectionEdit
          ? {selectedRowKeys:selecrowdata, ...objrowSelection }
          : null
      "
      :pagination="pagination ? objArray.pagination : false"
    >
      <template #bodyCell="{ column, record, index }">
        <slot name="customtable" :column="column" :record="record"></slot>
        <template v-if="column.key === 'operation'">
          <span>
            <slot name="operation" :column="column" :record="record"></slot>
            <a
              @click="editEvent('download', record)"
              v-if="operatingButton?.reportdownload"
            >
              报表下载</a
            >
            <a-divider type="vertical" v-if="dividerbutton?.reportdownload" />
            <a
              @click="editEvent('detail', record)"
              v-if="operatingButton?.detail"
            >
              查看</a
            >
            <a-divider type="vertical" v-if="dividerbutton?.detail" />
             <slot name="editOperation" :column="column" :record="record">
            <a @click="editEvent('edit', record)" v-if="operatingButton?.edit"
              >修改</a
            >
             </slot>
            <a-divider type="vertical" v-if="dividerbutton?.edit" />
            <a
              @click="delEvent(record)"
              v-if="operatingButton?.del"
              style="color: red"
              >删除</a
            >
            <a-divider type="vertical" v-if="dividerbutton?.del" />
          </span>
        </template>
        <template v-if="column.key === 'index'">
          <span>{{
            `${
              (objArray.pagination.current - 1) * objArray.pagination.pageSize +
              index +
              1
            }`
          }}</span>
        </template>
        <template v-if="column.key === objType.typeName && objType.isshow">
          <span class="blockBox" v-if="objType[record[objType.typeName]]"
            :style="{
              borderColor:objTypecolor.isshow
                ? objTypecolor[record[objType.typeName]]
                : '#fff',
              color: objTypecolor.isshow
                ? objTypecolor[record[objType.typeName]]
                : null,
              backgroundColor:objTypeBgcolor.isshow
                ? objTypeBgcolor[record[objType.typeName]]
                : null,

            }"
            
            >{{ objType[record[objType.typeName]] }}</span
          >
              <!-- marginLeft:objType.marginLeft?objType.marginLeft:'',
              marginRight:objType.marginRight?objType.marginRight:'' -->
          <span :style="{color:`#FF0000`,color:!objType[record[objType.typeName]]?'#999':''}" v-else>{{
                        objType[record[objType.typeName]]?  objType[record[objType.typeName]]:'暂无数据'
                    }}</span>
        </template>
        <template v-if="column.key === obj2Type?.typeName && obj2Type?.isshow">
          <span>{{ obj2Type[record[obj2Type.typeName]] }}</span>
        </template>
      </template>
    </a-table>
  </div>
</template>
<script setup>
import { reactive, ref, watch, toRefs } from "vue";

const props = defineProps({
  editColor:{
     type: Boolean,
    default: false,
  },
  ischange:{
     type: Boolean,
    default: true,
  },
  // 请求最大条数
  MaxResultCount: {
    type: Number,
    default: 0,
  },
  // 是否显示表头
  showHeader: {
    type: Boolean,
    default: true,
  },
  addbtnName: {
    type: String,
    default: "",
  },
  editTxt:{
    type: String,
    default: "修改",
  },
  operatingButton: {
    //操作按钮
    reportdownload: {
      type: Boolean,
      default: false,
    },
    edit: {
      type: Boolean,
      default: true,
    },
    del: {
      type: Boolean,
      default: true,
    },
    detail: {
      type: Boolean,
      default: false,
    },
  },
  dividerbutton: {
    //操作按钮之间的分割线
    reportdownload: {
      type: Boolean,
      default: false,
    },
    edit: {
      type: Boolean,
      default: true,
    },
    del: {
      type: Boolean,
      default: false,
    },
    detail: {
      type: Boolean,
      default: false,
    },
  },

  allDel: {
    //按钮:全部删除
    type: Boolean,
    default: false,
  },
  columns: {
    //表格表头
    type: Array,
    default: [],
  },
  formessagedivider: {
    type: Boolean,
    default: false,
  },
  hasImport: {
    //按钮:导入
    type: Boolean,
    default: false,
  },
  hasExport: {
    //按钮:导出
    type: Boolean,
    default: false,
  },
  markread: {
    // 按钮:标记已读
    type: Boolean,
    default: false,
  },
  hasDetail: {
    //表格详情
    type: Boolean,
    default: false,
  },
  tableOtherobj: {
    type: Object,
    default: {
      // hasAddbtn: true,// 表格上是否有添加按钮
      // hasDetail: false,//操作中是否有详情
      scroll: false, //表格是否有横向滚动,以及x,方向的 值是多少  number
      actionwidth: "120",
    },
  },
  hasedit: {
    //表格修改
    type: Boolean,
    default: true,
  },
  hasdel: {
    //表格删除
    type: Boolean,
    default: true,
  },
  hasseeprocess: {
    //表格查看过程
    type: Boolean,
    default: false,
  },

  pagination: {
    //分页
    type: Boolean,
    default: true,
  },

  // 是否有批量操作
  rowSelection: {
    type: Boolean,
    default: false,
  },
    rowSelectionEdit: {
    type: Boolean,
    default: false,
  },
  rowSelection2: {
    // 是否可以选择
    type: Boolean,
    default: false,
  },
  hasgoback: {
    //返回按钮
    type: Boolean,
    default: false,
  },
  searchkey: {
    // 查询的字段
    type: Object,
    default: {},
  },
  objType: {
    //后台返回摸个字段,不能直接显示,而是根据不同值显示对应的其他内容
    type: Object,
    default: {
      isshow: false, //是否显示
      typeName: "type", // 属性值 '需要转义的表格字段,当type=1时显示公司级;当typ=2时显示部门级'
      1: "公司级",
      2: "部门级",
    },
  },
  obj2Type: {
    //页面需要两个字段都用枚举时
    type: Object,
    default: {
      isshow: false, //是否显示
      typeName: "type", // 属性值 '需要转义的表格字段,当type=1时显示公司级;当typ=2时显示部门级'
      1: "公司级",
      2: "部门级",
    },
  },
  objTypecolor: {
    type: Object,
    default: {
      isshow: false, //是否显示
      typeName: "monitorDataReportType", // 属性值 '需要设置颜色的字段'
      day: "#FF0000",
      month: "#FFFF00",
    },
  },
    objTypeBgcolor: {
    type: Object,
    default: {
      isshow: false, //是否显示
      typeName: "monitorDataReportType", // 属性值 '需要设置颜色的字段'
      day: "#FF0000",
      month: "#FFFF00",
    },
  },
  expandIconSet: {
    // 表格嵌套时,那个控制的展开折叠图表的位置
    type: Object,
    default: {
      expandIconColumnIndex: 2, //想让展开图标放在第几列
      expandIconAsCell: false, 想让展开图标放在第几列 设置的配套属性
    },
  },

  loading: false, //表格loading
});
const {
  objTypecolor,
  obj2Type,
  operatingButton,
  dividerbutton,
  formessagedivider,
  markread,
  columns,
  hasImport,
  hasExport,
  hasDetail,
  tableOtherobj,
  hasedit,
  hasdel,
  hasseeprocess,
  pagination,
  rowSelection,
  rowSelectionEdit,
  hasgoback,
  searchkey,
  objType,
  expandIconSet,
} = toRefs(props);

// 发送给父组件的方法
const emits = defineEmits([
  "openModel",
  "handleDelTable",
  "getData",
  "FlagRead",
  "handleTableRowSelec",
  "exportXlsx",
  "importXlsx",
]);

// 批量删除
let flagselectedRowKeys = ref(true);
let selecrowdata = ref();
const objrowSelection = {
  // selectedRowKeys: selectedRowKeys,

  //selectedRowKeys 选中行的datasource 中元素key的值; selectedRows为所选元素中datasource 是一个数组。
  onChange: (selectedRowKeys, selectedRows) => {
    let falg = selectedRowKeys.length ? false : true;
    flagselectedRowKeys.value = falg;
    selecrowdata.value = [...selectedRowKeys];
    // console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
    emits("handleTableRowSelec", selectedRowKeys, selectedRows);
  },
};

// 返回
const handlegoback = () => {
  history.back();
};
// 操作
const editEvent = (param1, param2) => {
  emits("openModel", param1, param2);
};
//导出操作
const exportEvent = (param1) => {
  emits("exportEvent", param1);
};
const delEvent = (param1, param2) => {
  emits("handleDelTable", param1);
};
const manyEditEvent=(param1, param2)=>{
emits("handleEditTable", param1,selecrowdata.value);
}
const handleFlagRead = () => {
  emits("FlagRead", selecrowdata);
};
// 分页方法
let objArray = reactive({
  // 请求参数
  searchParams: {},
  // 分页信息
  pagination: {
    current: 1,
    total: 0,
    pageSize: props.MaxResultCount ? props.MaxResultCount : 25,
    showSizeChanger: props.ischange,
    showTotal: (total) => `共 ${total} 条`,
    pageSizeOptions: [ "15", "20", "25", "30", "40"],
    onChange: (page, pageSize) => {
      handleSizeChange(page, pageSize);
    },
  },
  // 批量选中
  selectedRowKeys: [],
  // 选中的行数据
  selectedRows: [],
});

const handleSizeChange = (page, pageSize) => {
  if (objArray.pagination.pageSize != pageSize) {
    objArray.pagination.current = 1;
    objArray.pagination.pageSize = pageSize;
  } else {
    objArray.pagination.current = page;
  }
  emits("getData", props.searchkey, objArray.pagination);
};
// 嵌套子表格
const handleexpand = (expanded, record) => {
  console.log(expanded, record, "expanded, record");
};
const expandedRowsChange = (expandedRows) => {
  console.log(expandedRows, "expandedRows");
};

// 导出全部
const handleAllExport = () => {
  emits("exportXlsx");
};
// 导入
const headers = {
  authorization: "authorization-text",
};
const fileList = ref([]);
const handleChange = (info) => {
  if (info.file.status !== "uploading") {
    console.log(info.file, info.fileList);
  }
  if (info.file.status === "done") {
    message.success(`${info.file.name} file uploaded successfully`);
  } else if (info.file.status === "error") {
    message.error(`${info.file.name} file upload failed.`);
  }
  emits("importXlsx", info);
};
const handleImportant = () => {};
const dataSource = ref([]);
const getData = (data, total) => {
  dataSource.value = data;
  objArray.pagination.total = total;
};
const setpage = (pageojb) => {
  objArray.pagination.current = pageojb.current;
  objArray.pagination.pageSize = pageojb.pageSize;
};
defineExpose({ getData, setpage,selecrowdata });
</script>
<style lang="less" scoped>
.btn-add {
  text-align: right;
  /* margin-bottom: 20px; */
  /* margin-top: 20px; */
}

:deep(.ant-select-single:not(.ant-select-customize-input)) {
  .ant-select-selector {
    height: 24px !important;
  }
}

:deep(.ant-select-single) {
  .ant-select-selector {
    .ant-select-selection-item {
      line-height: 22px !important;
    }
  }
}
.blockBox{
  padding: 0px 5px;
  // margin:0px 33px;
  border: 1px solid;
  border-radius: 3px;
  font-size: 14px;
}
</style>
相关推荐
多多*1 分钟前
Spring之Bean的初始化 Bean的生命周期 全站式解析
java·开发语言·前端·数据库·后端·spring·servlet
linweidong6 分钟前
在企业级应用中,你如何构建一个全面的前端测试策略,包括单元测试、集成测试、端到端测试
前端·selenium·单元测试·集成测试·前端面试·mocha·前端面经
满怀101526 分钟前
【HTML 全栈进阶】从语义化到现代 Web 开发实战
前端·html
东锋1.337 分钟前
前端动画库 Anime.js 的V4 版本,兼容 Vue、React
前端·javascript·vue.js
满怀10151 小时前
【Flask全栈开发指南】从零构建企业级Web应用
前端·python·flask·后端开发·全栈开发
小杨升级打怪中1 小时前
前端面经-webpack篇--定义、配置、构建流程、 Loader、Tree Shaking、懒加载与预加载、代码分割、 Plugin 机制
前端·webpack·node.js
Yvonne爱编码2 小时前
CSS- 4.4 固定定位(fixed)& 咖啡售卖官网实例
前端·css·html·状态模式·hbuilder
SuperherRo2 小时前
Web开发-JavaEE应用&SpringBoot栈&SnakeYaml反序列化链&JAR&WAR&构建打包
前端·java-ee·jar·反序列化·war·snakeyaml
大帅不是我2 小时前
Python多进程编程执行任务
java·前端·python
前端怎么个事2 小时前
框架的源码理解——V3中的ref和reactive
前端·javascript·vue.js