前端小功能:Word、PDF、Excel、log日志文档vue预览。

前端小功能:Word、PDF、Excel文档vue预览;log日志文件预览

要工具不区分框架,把FileReader()文件处理函数可以细细品读一下。

可以参考https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader文档

同时可以了解一下, Blob ArrayBuffer,等数据格式,ajax如何获取Blod的基本操作。

需要处理文件,必须缓存文件,缓存文件必须解决跨域问题。


js-word文档预览。

如果你的文档都是公网可以访问的,可以用微软提供的在线预览

<iframe src='https://view.officeapps.live.com/op/embed.aspx?src=http://remote.url.tld/path/to/document.doc' width='1366px' height='623px' frameborder='0'>
This is an embedded
<a target='_blank' href='http://office.com'>Microsoft Office</a>
document, powered by
<a target='_blank' href='http://office.com/webapps'>Office Online</a>
</iframe>

如果是本地文件,或者是内网文件则可以使用以下方法:

PDF:Vue-pdf

Word: mammoth.js

Excel: SheetJS

1. PDF文档预览示例:

npm install --save vue-pdf

PDF.vue

<template>
    <div>
          <pdf ref="pdf" :src="pdfUrl" style="width: 100%;" />
    </div>
</template>
<script>
import pdf from 'vue-pdf'
export default {
    data(){
        return: {
            pdfUrl: '',
        }
    }
    created() {
       const path = 'test.pdf'// 你获取到的pdf路径
       // pdf.createLoadingTask解决文件件跨域问题
       this.pdfUrl = pdf.createLoadingTask(path)
  },
}
</script>        

2. Word文档预览示例:

npm install --save mammoth

中文文档:https://www.kutu66.com/GitHub/article_106969#1-yfsys

mammoth.convertToHtml(input, options)

将源文档转换为 HTML。

  • input: 描述源文档的对象。 在 node.js 上,支持以下输入:

    • {path: path},其中 path 是. docx 文件的路径。
    • {buffer: buffer},其中 buffer 是包含. docx 文件的node.js 缓冲区。

    在浏览器中,支持以下输入:

    • {arrayBuffer: arrayBuffer},其中 arrayBuffer 是包含. docx 文件的array 缓冲区。

options ( 可选): 转换的选项。 

浏览器表示支持arrayBuffer

转换也仅仅支持docx

具体巧妙用法就请多自行去看文档。

Word.vue

<template>
    <div>
          <input id="document" type="file">
          <div v-html="vHtml" />
    </div>
</template>
<script>
import mammoth from 'mammoth'
export default {
    data(){
        return: {
            vHtml: '',
        }
    }
    mounted() {
 document.getElementById('document').addEventListener('change', this.uploading, false)
  },
methods: {
    uploading(event) {
      const that = this
      var file = event.target.files[0] // 获取文件
      var reader = new FileReader()
      reader.readAsArrayBuffer(file)
      reader.onload = function(e) {
        const buffer = e.target.result // 此时是arraybuffer类型
        mammoth.convertToHtml({ arrayBuffer: buffer }).then((result) => {
          console.log(result)
          that.vHtml = result.value
        }).done()
      }
    },
}
}
</script>        

3. Excel文档预览示例

npm install --save xlsx

中文文档:https://github.com/rockboom/SheetJS-docs-zh-CN

excel.vue<template>

  <div id="table">

    <div class="tab">
      <el-radio-group v-model="cardActive">
        <el-radio-button v-for="(item,index) in card" :label="item" :key="index" @click="chooseTable(item)"></el-radio-button>
      </el-radio-group>
    </div>

     <el-table
      :data="tableData"
      style="width: 100%">

      <el-table-column
        v-for="(value,key,index) in tableData"
        :key="index"
        :prop="key"
        :label="key">
      </el-table-column>
    </el-table>

  </div>
</template>

<script>
import XLSX from 'xlsx'
export default {
  data () {
    return {
      tableData: [],
      card: [],
      cardActive: '',
      workbook: {}

    }
  },
  watch: {
    cardActive (ov, nv) {
      this.getTable(ov)
    }
  },
  mounted () {
    this.readWorkbookFromRemoteFile('/static/o2.xlsx')
  },
  methods: {
    readWorkbookFromRemoteFile: function (url) {
      var xhr = new XMLHttpRequest()
      xhr.open('get', url, true)
      xhr.responseType = 'arraybuffer'
      let _this = this
      xhr.onload = function (e) {
        if (xhr.status === 200) {
          var data = new Uint8Array(xhr.response)
          var workbook = XLSX.read(data, {type: 'array'})
          console.log(workbook)

          var sheetNames = workbook.SheetNames // 工作表名称集合
          _this.workbook = workbook
          _this.card = sheetNames
          _this.cardActive = sheetNames[0]
          _this.getTable(sheetNames[0])
        }
      }
      xhr.send()
    },
    getTable (sheetName) {
    
var worksheet = this.workbook.Sheets[sheetName]
     // 表格列和字段描述,顺序位置改变的情况下必须修改,请仔细参考!!!。
this.tableData = XLSX.utils.sheet_to_json(worksheet,{
      header: [
        'index',
        'insureCompany',
        'cooperationTerm',
        'cooperationTange',
        'branchName',
        'serviceNumber',
        'onlineWay',
        'settlement',
        'solvency',
       ],
    })
      console.log(this.tableData)
    }
  }
}
</script>

<style lang="stylus" scoped>
#table
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  margin-top: 60px;
  border 1px solid #ebebeb
  padding 20px
  width 80%
  margin 20px auto
  border-shadow 0 0 8px 0 rgba(232,237,250,.6), 0 2px 4px 0 rgba(232,237,250,.5)
  border-radius 10px
  overflow scroll
  height 100%
  .tab
    margin 0 0 20px 0
    display flex
    flex-direction row
</style>

<style scoped>
.is-active{
  background-color:#409EFF
}
span{
  background-color:red
}

</style>

注: 文档使用绝对路径的时候,先解决跨域的问题。

3.1  Excel文档转换js文件,node脚本生成文件

node将Excel文件转换成js导出文件。

用一个轻便的库 node-xlsx,只有14k,比起xlsx的10mb,实在是好太多了

const xlsx = require('node-xlsx');
const fs = require('fs');
const path = require('path');
const nunjucks = require('nunjucks');

/**
 * 使用node脚本更新合作保险公司数据
 * 信息修改后,启动 npm run node:xlsx 更新文件
 * 注意 !!!观察表格列和字段是否匹配,是否有新增修改导致index错乱。
 * @param fileName 文档名称
 * @param sheetName 指定拉取表格名称
 * @param startRow excel文件里的表格一般有标题所以不一定从0开始
 */
const custom = {
  fileName: '合作保险公司1.12.xlsx',
  sheetName: '合作保险公司(1.12更新)',
  startRow: 2,
};

// 文件模板
function getTmpl() {
  const tmpl = `/**
 * @param companyName 公司简称 // 1.0版本
 * @param insureCompany 公司名称
 * @param branchName 省级分支机构和落地服务机构的省
 * @param serviceNumber 全国统一客服电话
 * @param onlineWay 在线服务访问方式
 * @param verification 保单验证 // 1.0版本
 * @param cooperationTerm 合作期限
 * @param cooperationTange 合作范围
 * @param solvency 偿付能力、风险综合评级、消费者权益保护
 * @param settlement 理赔争议处理
 */
export default [
  {% for Sheet in sheetsArray %}{
    companyName: "{{Sheet.companyName}}",
    insureCompany: "{{Sheet.insureCompany}}",
    branchName: "{{Sheet.branchName}}",
    serviceNumber: "{{Sheet.serviceNumber}}",
    onlineWay: "{{Sheet.onlineWay}}",
    verification: "{{Sheet.verification}}",
    cooperationTerm: "{{Sheet.cooperationTerm}}",
    cooperationTange: "{{Sheet.cooperationTange}}",
    solvency: "{{Sheet.solvency}}",
    settlement: "{{Sheet.settlement}}",
  },{% endfor %}
];
`;
  return tmpl;
}
// 单独处理换行符
function handleSettlement(str) {
  if (str && typeof str === 'string') {
    const newStr = str.replace(/\n/g, '^_^').replace(/\s/g, '');
    return newStr;
  }
  return str;
}
// 清空字符串换行和空格
function handleClear(str) {
  if (str && typeof str === 'string') {
    return str.replace(/\n/g, '').replace(/\s/g, '');
  }
  return str;
}
const dirPath = path.resolve(__dirname, custom.fileName);
// 表格列和字段描述,顺序位置改变的情况下必须修改,请仔细参考!!!。
const sheets = xlsx.parse(dirPath, {
  header: [
    'index',
    'insureCompany',
    'cooperationTerm',
    'cooperationTange',
    'branchName',
    'serviceNumber',
    'onlineWay',
    'settlement',
    'solvency',
  ],
});
const sheetsArray = [];
// sheets是一个数组,数组中的每一项对应这个文件里的多个表格
sheets.forEach(function (sheet) {
  // 指定拉取表格名称
  if (sheet.name === custom.sheetName) {
    sheet.data.forEach((item, index) => {
      if (index > custom.startRow) {
        // 处理数据字符串格式转换, 兼容字段等
        sheetsArray.push({
          ...item,
          companyName: item['insureCompany'],
          serviceNumber: handleClear(item['serviceNumber']),
          onlineWay: handleClear(item['onlineWay']),
          verification: handleClear(item['onlineWay']),
          settlement: handleSettlement(item['settlement']),
        });
      }
    });
  }
});
// 生成or覆盖文件。
const outFile = path.resolve(__dirname, 'inCompany.js');
fs.writeFileSync(
  outFile,
  nunjucks.renderString(getTmpl(), {
    sheetsArray,
  })
);
console.warn(`node:xlsx file: ${outFile} success`);

通过nunjucks模板语法对文档内容进行生成,node对文档的处理,生成对应的数据结构文档,这个方法同时也适用其他的文档转换。Excel转js,Excel转json,等数据文档转换,也是可以的。

 

4. log日志文件预览
word等文档显示,部分样式需要一些基础的库来提供支持,对于log日志形式搜索了一下,基本没有相关的库,一般情况下,如果log是后台生成的,可以让后台直接转json,每一行为一个list,前端直接循环列表显示就OK。

遇到特殊情况,log并非后台生成,第三方平台生成,不经过后台服务的时候,转换json可以就无法实现了。

log前端只能拿到URL的情况,那就直接转文本显示就好了。

非常简单:获取Blob,转换text文本就可以直接显示。

  // 创建XMLHttpRequest对象
    let xhr = new XMLHttpRequest()
    // 配置请求方式、请求地址以及是否同步
    xhr.open('GET', baseUrl, true)
    // 设置请求结果类型为blob
    xhr.responseType = 'blob'
    // 请求成功回调函数
    xhr.onload = function(option:any) {
      let res = option.target
      if (res.status === 200) {
        let blob = res.response
        let reader = new FileReader();
        reader.readAsText(blob, 'utf-8');
        reader.onload = function () {
          let data:any = reader.result
          setLogHtml(data)
        }
        if(tip){
          message.success({
            content: '刷新完成'
          })
        }
      }else{
        message.error({
          content: '服务异常'
        })
        setLogHtml('#暂无日志详情')
      }
    }
    xhr.send()

文本可以直接展示的,可能不太雅观,部分换行无法体现。因为是文本,只有给一个textarea,应该就可以解决部分不换行的问题。

如果能力有余,用个代码编辑器,那就很完美了。https://monaco-react.surenatoyan.com/

 

 

没有终点,没有彼岸,坚持就好,愿岁月如初

posted @ 2020-06-09 14:32  smallbore  阅读(15394)  评论(6编辑  收藏  举报
回顶部