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>
相关推荐
cs_dn_Jie30 分钟前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic1 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿1 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具2 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
qq_390161772 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test3 小时前
js下载excel示例demo
前端·javascript·excel
Yaml43 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事3 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶3 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo3 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx