草庐IT

Vue前端实现excel的导入、导出、打印功能

Litt_White 2023-04-22 原文

目录

一、相关依赖下载

导入导出依赖:
npm install xlsx@0.16.9
npm install xlsx-style@0.8.13 --save

  1. 安装xlsx-style,运行报错
    This relative module was not found: ./cptable in ./node_modules/xlsx-style@0.8.13@xlsx-style/dist/cpexcel.js
  2. 解决报错
    在\node_modules\xlsx-style\dist\cpexcel.js 807行 的var cpt = require('./cpt' + 'able');改为:var cpt = cptable;

打印依赖:
npm install vue-print-nb@1.7.5 --save

二、excel导入功能

<template>
  <div>
    <el-upload
      action="#"
      :before-upload="beforeUpload"
      :show-file-list="false"
      accept=".xlsx, .xls"
    >
      <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
    </el-upload>
    <!-- 解析出来的数据 -->
    <el-table :data="tableData">
      <el-table-column prop="日期" label="日期" width="180"> </el-table-column>
      <el-table-column prop="姓名" label="姓名" width="180"> </el-table-column>
      <el-table-column prop="地址" label="地址"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
import XLSX from 'xlsx'
export default {
  name: 'importExcel',
  data () {
    return {
      tableData: [],
    }
  },
  methods: {
    beforeUpload (file) {
      console.log(file, '--文件');
      this.file2XLSX(file).then((res) => {
        console.log('可以继续对res数据进行二次处理')
        this.tableData = res[0].sheet
      })
      return false
    },
    // excel导入方法
    file2XLSX (file) {
      return new Promise(function (resolve, reject) {
        // 通过FileReader对象读取文件
        const reader = new FileReader()
        // 读取为二进制字符串
        reader.readAsBinaryString(file)
        reader.onload = function (e) {
          console.log(e, '读取文件成功的e');
          // 获取读取文件成功的结果值
          const data = e.target.result
          // XLSX.read解析数据,按照type 的类型解析
          let wb = XLSX.read(data, {
            type: 'binary' // 二进制
          })
          console.log(wb, '---->解析后的数据')
          // 存储获取到的数据
          const result = []
          // 工作表名称的有序列表
          wb.SheetNames.forEach(sheetName => {
            result.push({
              // 工作表名称
              sheetName: sheetName,
              // 利用 sheet_to_json 方法将 excel 转成 json 数据
              sheet: XLSX.utils.sheet_to_json(wb.Sheets[sheetName]) 
            })
          })
          resolve(result)
        }
      })
    }
  },
}
</script>

三、table导出excel表格

1.导出行数据

2.导出table数据(也会导出合并单元格)

3.导出二维数据的table数据

4.导出合并单元格table数据

<template>
  <div>
    <el-button type="primary" @click="exportSelectData"
      >导出行数据(json_to_sheet)</el-button
    >
    <el-button type="primary" @click="exportTableData"
      >导出table数据(也会导出合并单元格)(table_to_sheet)</el-button
    >
    <el-button type="primary" @click="exportTableDataFormAoa"
      >导出二维数据的table数据(aoa_to_sheet)</el-button
    >
    <el-button type="primary" @click="exportTableDataCellMerging"
      >导出合并单元格table数据(aoa_to_sheet)</el-button
    >
    <el-table
      :data="tableData"
      @selection-change="handleSelectionChange"
      ref="tableDataRef"
      id="table1"
    >
      <el-table-column type="selection" width="55"> </el-table-column>
      <el-table-column prop="date" label="日期" width="180"> </el-table-column>
      <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
      <el-table-column prop="address" label="地址"> </el-table-column>
    </el-table>
  </div>
</template>

<script>
import XLSX from 'xlsx'
export default {
  name: 'importExcel',
  data () {
    return {
      selectionList: [],
      tableData: [{
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1518 弄'
      }, {
        date: '2016-05-04',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1517 弄'
      }, {
        date: '2016-05-01',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1519 弄'
      }, {
        date: '2016-05-03',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1516 弄'
      }]
    }
  },
  methods: {
    // 获取选择的行数据
    handleSelectionChange (val) {
      this.selectionList = val;
      console.log(this.selectionList, '--行数据');
    },
    // 导出选择的行数据
    exportSelectData () {
      // 对选择的表格数据处理:添加标题
      let arr = this.selectionList.map(item => {
        return {
          日期: item.date,
          姓名: item.name,
          地址: item.address
        }
      })
      // 将json数据变为sheet数据
      // json_to_sheet: 将一个由对象组成的数组转成sheet;
      let sheet = XLSX.utils.json_to_sheet(arr)
      // 新建表格
      let book = XLSX.utils.book_new()
      // 在表格中插入一个sheet
      XLSX.utils.book_append_sheet(book, sheet, "sheet1")
      // 通过xlsx的writeFile方法将文件写入
      XLSX.writeFile(book, `user${new Date().getTime()}.xls`)
    },
    // 导出table数据
    exportTableData () {
      // 获取dom元素(2种方式)
      // let table1 = document.querySelector("#table1");  // 原生dom
      let table = this.$refs.tableDataRef.$el
      // table_to_sheet: 将一个table dom直接转成sheet,会自动识别colspan和rowspan并将其转成对应的单元格合并;
      let sheet = XLSX.utils.table_to_sheet(table)
      let book = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(book, sheet, "sheet1")
      XLSX.writeFile(book, `user${new Date().getTime()}.xls`)
    },
    // 导出一个二维数组
    exportTableDataFormAoa () {
      let aoa = [
        ['姓名', '性别', '年龄', '注册时间'],
        ['张三', '男', 18, new Date()],
        ['李四', '女', 22, new Date()]
      ];
      // 将一个二维数组转成sheet
      // aoa_to_sheet: 这个工具类最强大也最实用了,将一个二维数组转成sheet,会自动处理number、string、boolean、date等类型数据;
      let sheet = XLSX.utils.aoa_to_sheet(aoa);
      let book = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(book, sheet, "sheet1")
      XLSX.writeFile(book, `user${new Date().getTime()}.xls`)
    },
    // 导出合并单元格的table数据
    exportTableDataCellMerging () {
      let aoa = [
        ['主要信息', null, null, '其它信息'], // 特别注意合并的地方后面预留2个null
        ['姓名', '性别', '年龄', '注册时间'],
        ['张三', '男', 18, new Date()],
        ['李四', '女', 22, new Date()]
      ];
      let sheet = XLSX.utils.aoa_to_sheet(aoa);
      // 设置合并的单元格
      sheet['!merges'] = [
        // 设置A1-C1的单元格合并
        { s: { r: 0, c: 0 }, e: { r: 0, c: 2 } }
      ];
      let book = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(book, sheet, "sheet1")
      XLSX.writeFile(book, `user${new Date().getTime()}.xls`)
    }
  }
}
</script>

参考

  1. 对sheet二次处理的参考:
    https://blog.csdn.net/tian_i/article/details/84327329

四、table导出excel表格(带样式)

1.导出带样式的excel

<template>
  <div>
    <el-button @click="exportExcel()">导出带样式的excel</el-button>
  </div>
</template>

<script>
import XLSX from 'xlsx'
import XLSXStyle from 'xlsx-style';

export default {
  name: 'exportExcelStyle',
  methods: {
    exportExcel () {
      let data = [['时间', '电压'], ['2021-12-01 08:57:12', '3.14'], ['2021-12-01 08:58:20', '3.15']];
      let titles = ['时间', '电压']
      var sheet = XLSX.utils.json_to_sheet(data, {
        skipHeader: true,
      });
      /**设置标题头背景色 */
      for (const key in sheet) {
        // 第一行,表头
        if (key.replace(/[^0-9]/ig, '') === '1') {
          sheet[key].s = {
            fill: { //背景色
              fgColor: { rgb: 'C0C0C0' }
            },
            font: {//字体
              name: '宋体',
              sz: 12,
              bold: true
            },
            border: {//边框
              bottom: {
                style: 'thin',
                color: 'FF000000'
              }
            },
            alignment: {
              horizontal: 'center' //水平居中
            }
          }
        }
        // 指定单元格样式
        if (key === 'A1') {
          sheet[key].s = {
            ...sheet[key].s,
            fill: { //背景色
              fgColor: { rgb: 'E4DFEC' }
            }
          }
        }
        // 列宽
        let colsP = titles.map(item => {
          let obj = {
            'wch': 25 //列宽
          }
          return obj;
        })
        sheet['!cols'] = colsP;//列宽

        // // 每列的列宽
        // sheet["!cols"] = [{
        //   wpx: 70 //单元格列宽
        // }, {
        //   wpx: 70
        // }, {
        //   wpx: 70
        // }, {
        //   wpx: 70
        // }, {
        //   wpx: 150
        // }, {
        //   wpx: 120
        // }];
      }
      let fileName = 'Excel文件.xlsx'
      let sheetName = 'Excel文件'
      this.openDownload(this.sheet2blob(sheet, sheetName), fileName);
    },
    sheet2blob (sheet, sheetName) {
      let wb = XLSX.utils.book_new();
      wb.SheetNames.push(sheetName)
      wb.Sheets[sheetName] = sheet;
      // 必须使用xlsx-style才能生成指定样式
      var wbout = XLSXStyle.write(wb, { bookType: '', bookSST: false, type: 'binary' })
      var blob = new Blob([s2ab(wbout)], { type: "" }, sheetName);
      // 字符串转ArrayBuffer
      function s2ab (s) {
        var buf = new ArrayBuffer(s.length);
        var view = new Uint8Array(buf);
        for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
        return buf;
      }
      return blob;
    },
    openDownload (url, saveName) {
      if (typeof url == "object" && url instanceof Blob) {
        url = URL.createObjectURL(url); // 创建blob地址
      }
      var aLink = document.createElement("a");
      aLink.href = url;
      aLink.download = saveName || ""; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
      var event;
      if (window.MouseEvent) event = new MouseEvent("click");
      else {
        event = document.createEvent("MouseEvents");
        event.initMouseEvent(
          "click",
          true,
          false,
          window,
          0,
          0,
          0,
          0,
          0,
          false,
          false,
          false,
          false,
          0,
          null
        );
      }
      aLink.dispatchEvent(event);
    }
  },
}
</script>

2. 结合el-table,根据勾选的内容,导出excel表格

html和css就不写了,主要记录下js功能实现的过程

// 导出函数
export async function exportBtn (payloadList) {
  // payloadList是table表格勾选的内容数组
  if (payloadList.length === 0) {
    this.$message({
      type: 'warning',
      message: '请选择要导出的记录!'
    })
  } else {
    // 最终生成sheet的aoelist
    let finalList = []
    // 一、准备枚举值
    // 1.写死
    let ywlxenum = [
      { label: '预审选址', value: 'YSXZ' },
      { label: '土地储备', value: 'TDCBGM' },
      { label: '农转用报批', value: 'YDBP' },
      { label: '规划条件', value: 'GHTJ' },
      { label: '行政划拨', value: 'XZHB' },
      { label: '公开出让', value: 'GKCR' },
      { label: '建设用地规划许可', value: 'JSYDGHXK' },
      { label: '建设工程规划类许可证核发', value: 'JSGCGHXK' },
      { label: '建设工程竣工规划核实', value: 'JGGHHY' },
      { label: '竣工验收备案', value: 'JGYSBA' }
    ]
    // 2.通过请求获取
    let ydxzenum = []
    await getEnumByValue({ value: 'TDLYXZ' }).then(data => {
      ydxzenum = mapListFunc(data.fieldEnum)
    })
    // 二、通过请求获取数据
    let resList = [] // 保存请求数据
    for (let i = 0; i < payloadList.length; i++) {
      await this.queryInfo({ id: payloadList[i].xmguid }).then(res => {
      	// 这里是判断了返回值里还包含了list数组
        if (res.data.bizGhtjGhqkList.length !== 0) {
          let bizGhtjGhqkList = res.data.bizGhtjGhqkList
          bizGhtjGhqkList.forEach(item => {
            resList.push({ ...res.data.bizSlsq, ...res.data.bizGhtj, ...item })
          })
        } else {
          resList.push({ ...res.data.bizSlsq, ...res.data.bizGhtj })
        }
      })
    }
    // 三、映射关系list
    let mappingList = [
      { field: 'xmmc', value: '项目名称', merge: true }, // merge代表单元格是否合并
      { field: 'ydxz', value: '用地性质', enum: true, merge: true }, // enum代表是否是枚举值
      { field: 'dkbh', value: '地块编号' },
    ]
    // 四、添加标题
    let titleList = []
    mappingList.forEach(item => {
      titleList.push(item.value)
    })
    finalList.push(titleList)
    // 五、添加内容
    resList.forEach(row => {
      // 行的list
      let ctnList = []
      let hyfltemp = []
      let ydxztemp = []
      mappingList.forEach(item => {
        if (item.enum) {
          // 带枚举值的处理
          switch (item.field) {
            case 'hyfl':
              hyfltemp = row[item.field] && row[item.field].split(',')
              ctnList.push(queryEnumVal(hyflenum, hyfltemp && hyfltemp[(hyfltemp.length - 1)]))
              break
            case 'ydxz':
              ydxztemp = row[item.field] && row[item.field].split(',')
              ctnList.push(queryEnumVal(ydxzenum, ydxztemp && ydxztemp[(ydxztemp.length - 1)]))
              break
            case 'pzjg':
              ctnList.push(queryEnumVal(pzjgenum, row[item.field]))
              break
            case 'ywlx':
              ctnList.push(queryEnumVal(ywlxenum, row[item.field]))
              break
            case 'cbywlx':
              ctnList.push(queryEnumVal(cbywlxenum, row[item.field]))
              break
            default:
              break
          }
        } else {
          // 常规
          ctnList.push(row[item.field])
        }
      })
      finalList.push(ctnList)
    })
    // 六、处理合并单元格
    let mergeArr = []
    let { indices } = unipFunc(resList, 'xmguid')
    mappingList.forEach((item, index) => {
      if (item.merge) {
        indices.forEach(itemlist => {
          if (itemlist.length > 1) {
            mergeArr.push({
              s: { r: itemlist[0] + 1, c: index },
              e: { r: itemlist[itemlist.length - 1] + 1, c: index }
            })
          }
        })
      }
    })
    // 七、生成sheet
    let sheet = XLSX.utils.aoa_to_sheet(finalList)
    // 八、合并单元格和添加样式
    sheet['!merges'] = mergeArr
    Object.keys(sheet).forEach((item, index) => {
      if (sheet[item].t) {
        sheet[item].s = { // 对齐方式相关样式
          alignment: {
            vertical: 'center', // 垂直对齐方式
            horizontal: 'center' // 水平对齐方式
            // wrapText: true // 自动换行
          }
        }
      }
    })
    // 九、导出excel
    openDownloadDialog(sheet2blob(sheet), new Date().getTime() + '.xlsx' || '表名.xlsx')
  }
}

function queryEnumVal (enumList, field) {
  // 获取枚举值对应的key
  let enumVal = ''
  enumList.forEach(item => {
    if (item.value === field) {
      enumVal = item.label
    }
  })
  return enumVal
}
function mapListFunc (params) {
  // 处理枚举值
  let list = []
  list = params.map(item => {
    item.value = item.enumValue
    item.label = item.enumName
    return item
  })
  return list
}
// 处理数据重复值
function unipFunc (list, objKey) {
  let key = {} // 存储的 key 是type的值,value是在indeces中对应数组的下标
  let indices = [] // 数组中每一个值是一个数组,数组中的每一个元素是原数组中相同type的下标
  list.map((item, index) => {
  // 根据对应字段 分类(type)
    let itemKey = item[objKey]
    let _index = key[itemKey]
    if (_index !== undefined) {
      indices[_index].push(index)
    } else {
      key[itemKey] = indices.length
      indices.push([index])
    }
  })
  // 归类结果
  let result = []
  let resultIndex = []
  indices.map((item) => {
    item.map((index) => {
      if (item.length > 1) {
        result.push(list[index])
        resultIndex.push(index)
      }
    })
  })
  return { result, resultIndex, indices }
}
// 下载excel
function openDownloadDialog (url, saveName) {
  if (typeof url === 'object' && url instanceof Blob) {
    url = URL.createObjectURL(url) // 创建blob地址
  }
  var aLink = document.createElement('a')
  aLink.href = url
  aLink.download = saveName || '' // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
  var event
  if (window.MouseEvent) event = new MouseEvent('click')
  else {
    event = document.createEvent('MouseEvents')
    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
  }
  aLink.dispatchEvent(event)
}
// 字符串转ArrayBuffer
function s2ab (s) {
  var buf = new ArrayBuffer(s.length)
  var view = new Uint8Array(buf)
  for (var i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
  return buf
}
// 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
function sheet2blob (sheet, sheetName) {
  sheetName = sheetName || 'sheet1'
  let workbook = XLSX.utils.book_new()
  workbook.SheetNames.push(sheetName)
  workbook.Sheets[sheetName] = sheet
  // 生成excel的配置项
  var wopts = {
    bookType: 'xlsx', // 要生成的文件类型
    bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
    type: 'binary'
  }
  var wbout = XLSXStyle.write(workbook, wopts)
  var blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' })

  return blob
}

参考

  1. 带样式的导出参考代码:
    https://blog.csdn.net/weixin_39246975/article/details/121639072
  2. 别人对xlsx-style的二次封装:
    https://blog.csdn.net/weixin_51947053/article/details/127370479

五、打印功能

1.直接使用window自带的打印功能: window.print()

<template>
  <div>
    <p>点击下面的按钮,可将页面进行打印</p>
    <div id="printDiv">
      <p>打印内容 </p>
      <p>打印内容 </p>
      <p>打印内容 </p>
      <p>打印内容 </p>
    </div>
    <button @click="print">打印页面内容</button>
  </div>
</template>

<script>
  export default{
    methods: {
      print(){
        window.print()
      }
    }
  }
</script>

2.使用打印插件:vue-print-nb

1、安装 vue-print-nb:

// vue2.x 版本
npm install vue-print-nb --save   
// vue3.x 版本
npm install vue3-print-nb --save

2、在项目中引入 vue-print-nb:

// vue2.x版本 -- 全局引入:在项目中入口文件 main.js 文件中全局引入 vue-print-nb
import Vue from 'vue'
import Print from 'vue-print-nb'
Vue.use(Print)

// 局部引入报错,还不知道咋解决,建议是全局引入
// vue2.x版本 -- 在需要打印功能的页面引入 vue-print-nb
import print from 'vue-print-nb'
export default{
    directives: { print }
}

// vue3.x版本 -- 全局引入:在项目中入口文件 main.js 文件中全局引入 vue3-print-nb
import {createApp} from 'vue'
import App from './App'
import Print from 'vue3-print-nb'
const app = createApp(App)
app.use(Print)
app.mount('#app')

// vue3.x版本 -- 在需要打印功能的页面引入 vue3-print-nb
import print from 'vue3-print-nb'
export default{
    directives: { print }
}

3、使用 vue-print-nb 实现打印功能

① 实现方式1:打印区域设置id, 打印按钮绑定此 id

<template>
  <div>
    <p>点击下面的按钮,可将div里的内容区域进行打印</p>

    <div id="printDiv">
      <p>打印内容 </p>
      <p>打印内容 </p>
      <p>打印内容 </p>
      <p>打印内容 </p>
    </div>

    <button v-print="'#printDiv'">打印id为printDiv的div区域内容</button>
  </div>
</template>

<script>
  export default{
    data(){
      return{}
    }
  }
</script>

② 实现方式2:打印区域设置id, 打印按钮进行打印配置

<template>
  <div>
    <p>点击下面的按钮,可将div里的内容区域进行打印</p>

    <div id="printDiv">
      <p>打印内容 </p>
      <p>打印内容 </p>
      <p>打印内容 </p>
      <p>打印内容 </p>
    </div>

    <button v-print="'printSet'">打印id为printDiv的div区域内容</button>
  </div>
</template>

<script>
  export default{
    data(){
      return{
        printSet: {
          id: 'printDiv',
          extraCss: "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
          extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
          beforeOpenCallback (vue) {
            console.log('打开之前')
          },
          openCallback (vue) {
            console.log('执行了打印')
          },
          closeCallback (vue) {
             console.log('关闭了打印工具')
          }
        }
      }
    }
  }
</script>

③ 打印网址:打印指定url(同一个同源策略)对应的内容

<template>
    <button v-print="'printSet'">打印网址</button>
</template>

<script>
  export default{
    data(){
      return{
        printSet: {
          url: 'http://localhost:8080/',
          beforeOpenCallback (vue) {
            console.log('打开之前')
          },
          openCallback (vue) {
            console.log('执行了打印')
          },
          closeCallback (vue) {
             console.log('关闭了打印工具')
          }
        }
      }
    }
  }
</script>

④ 打印预览功能

<template>
    <button v-print="'printSet'">打印+预览功能</button>
</template>

<script>
  export default{
    data(){
      return{
        printSet: {
          url: 'http://localhost:8080/', // 打印网页预览  如果想要打印本地预览,那么可以不用提供url,需提供打印区域的id,例如: id: 'printDiv'
          preview: true,
          previewTitle: 'Test Title',
          previewBeforeOpenCallback (vue) {
            console.log('正在加载预览窗口')
          },
          previewOpenCallback (vue) {
            console.log('已经加载完预览窗口')
          },
          beforeOpenCallback (vue) {
            console.log('打开之前')
          },
          openCallback (vue) {
            console.log('执行了打印')
          },
          closeCallback (vue) {
             console.log('关闭了打印工具')
          }
        }
      }
    }
  }
</script>

⑤ 打印异步url

<template>
    <button v-print="'printSet'">打印+预览功能</button>
</template>

<script>
  export default{
    data(){
      return{
        printSet: {
          asyncUrl (reslove, vue) {
             setTimeout(() => {
                reslove('http://localhost:8080/')
             }, 2000)
            }, // 异步url
          preview: true,
          previewTitle: 'Test Title',
          previewBeforeOpenCallback (vue) {
            console.log('正在加载预览窗口')
          },
          previewOpenCallback (vue) {
            console.log('已经加载完预览窗口')
          },
          beforeOpenCallback (vue) {
            console.log('打开之前')
          },
          openCallback (vue) {
            console.log('执行了打印')
          },
          closeCallback (vue) {
             console.log('关闭了打印工具')
          }
        }
      }
    }
  }
</script>

⑥ 实现区域不打印方式

<template>
    <div>
        <div ref="printDiv">
            <p>打印内容区域</p>
            <p>打印内容区域</p>
            <p>打印内容区域</p>
            <p>打印内容区域</p>
            <p>打印内容区域</p>
    

            实现区域不打印方式1:设置class为 no-print 即可实现该区域不打印
            <p class="no-print">不要打印的内容区域</p>

            // 实现区域不打印方式2: 自定义不打印区域的class名
            <p class="do-not-print-div">不要打印的内容区域</p>
        </div> 

        <button @click="printBtnClick">打印按钮</button>       
    </div>
</template>

<script>
export default{
    data(){
        return {}
    },
    methods:{
        printBtnClick(){
            // 注意必须使用ref指定打印区域,如果通过id或者class,那么wenpack打包后打印区域会为空
            this.$print(this.$refs.printDiv) 

            // 实现区域不打印方式2
            this.$print(this.$refs.print, { noPrint: '.do-not-print-div' }) 
        },
    }
}
</script>

⑦ vue-print-nb的API配置如下

1、id: String // 范围打印 ID,必填值

2、standard: String   // 文档类型(仅打印本地范围)

3、extraHead: String // <head></head>在节点中添加DOM节点,并用,(Print local range only)分隔多个节点

4、extraCss: String  // <link>新的 CSS 样式表,并使用,(仅打印本地范围)分隔多个节点

5、popTitle: String // <title></title> 标签内容(仅打印局部范围)

6、openCallback: Function // 调用打印工具成功回调函数

7、closeCallback: Function // 关闭打印工具成功回调函数

8、beforeOpenCallback: Function // 调用打印工具前的回调函数

9、url: String // 打印指定的 URL。(不允许同时设置ID)

10、asyncUrl: Function // 异步网址:通过 'resolve()' 和 Vue 返回 URL

11、preview: Boolean // 预览

12、previewTitle: String // 预览标题

13、previewPrintBtnLabel: String // 预览按钮的名称

14、zIndex: String,Number // 预览CSS:z-index

15、previewBeforeOpenCallback: Function // 启动预览工具前的回调函数

16、previewOpenCallback: Function // 预览工具完全打开后的回调函数

17、clickMounted: Function //点击打印按钮的回调函数

有关Vue前端实现excel的导入、导出、打印功能的更多相关文章

  1. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  2. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  3. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  4. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  7. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  8. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  9. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  10. ruby - Arrays Sets 和 SortedSets 在 Ruby 中是如何实现的 - 2

    通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复

随机推荐