由于移动端H5项目需要预览不同形式的文件,自己的项目是v3+ts+vite,用的setup语法塘.虽然解决方案与网上大同小异,但还是踩了一些坑,在这里记录一下。因为用的第三方库,不了解一些具体的数据类型,因此偷懒用了any去处理。
pdf预览
主要通过pdfjs-dist预览,主要考虑到可以实现自己的定制化需求,直接npm安装即可使用,我的版本是2.5.207
npm install pdfjs-dist
//ts 引入
import * as PDFJS from 'pdfjs-dist'
//添加这行解决worker.
PDFJS.GlobalWorkerOptions.workerSrc ='https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.worker.js'
具体使用借鉴的是网上代码,原文链接我暂时没找到,如果看到可以告诉我我附上转载链接。
<!--界面-->
<div class="preview-pdf">
<div :style="`margin:0 auto;width:${pdfWidth};`">
<canvas
v-for="page in pdfPages"
:id="'pdfCanvas' + page"
:key="page"
/>
</div>
</div>
具体调用方法
const pdfPages = ref<any>([])
const pdfWidth = ref('')
const pdfDoc = ref<any>('')
const pdfScale = 1.0
const pdfSrc = ref('')
const loadFile = (url) => {
const CMAP_URL = 'https://unpkg.com/pdfjs-dist@2.5.207/cmaps/'
const loadingTask = PDFJS.getDocument({
url: url,
withCredentials: false, // 携带凭证
cMapUrl: CMAP_URL,
cMapPacked: true,
httpHeaders: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, OPTIONS',
'Access-Control-Expose-Headers': 'Accept-Ranges, Content-Encoding, Content-Length, Content-Range'
}
})
loadingTask.promise.then(pdf => {
pdfDoc.value = pdf as any
pdfPages.value = pdf.numPages
nextTick(() => {
renderPage(1)
})
})
}
const renderPage = (num) => {
pdfDoc.value.getPage(num).then(page => {
const canvas = document.getElementById('pdfCanvas' + num) as any
const ctx = canvas.getContext('2d')
const dpr = window.devicePixelRatio || 1
const bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1
const ratio = dpr / bsr
const viewport = page.getViewport({ scale: pdfScale })
canvas.width = viewport.width * ratio
canvas.height = viewport.height * ratio
canvas.style.width = viewport.width + 'px'
pdfWidth.value = viewport.width + 'px'
canvas.style.height = viewport.height + 'px'
ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
// 将 PDF 页面渲染到 canvas 上下文中
const renderContext = {
canvasContext: ctx,
viewport: viewport
}
page.render(renderContext)
if (pdfPages.value > num) {
renderPage(num + 1)
}
})
}
使用
loadFile(pdf后缀文件地址)
excel
使用的是xlsx.js,0.18.5版本,界面上用了elment-plus2.1.5,与我typeScript版本4.5.2兼容的版本,不然打包会报一些ts类型找不到的错误。也可以自己封装一个table组件使用,因为我的项目对于excel的效果要求不是很高,所以没有选择费时间自己去封装,而是引入特定的el-table。
<el-table :data="tableData" style="width: 100%">
<el-table-column
v-for="(value,key,index) in tableData[2]"
:key="index"
:prop="key+''"
:label="key+''"
/>
</el-table>
主要方法
import * as XLSX from 'xlsx'
const tableData = ref([])
const workbook = ref({} as any)
const getTable = (sheetName:string) => {
const worksheet = workbook.value.Sheets[sheetName]
tableData.value = XLSX.utils.sheet_to_json(worksheet)
console.log(tableData.value)
}
const getExcel = (url) => {
const xhr = new XMLHttpRequest()
xhr.open('get', url, true)
xhr.responseType = 'arraybuffer'
xhr.onload = function(e) {
if (xhr.status === 200) {
const data = new Uint8Array(xhr.response)
const res = XLSX.read(data, { type: 'array' })
const sheetNames = res.SheetNames // 工作表名称集合
workbook.value = res
console.log(workbook.value)
getTable(sheetNames[0])
}
}
xhr.send()
}
调用
getExcel(文件地址)
word
采用mammoth,安装的是1.4.21版本 界面
<div id="wordView" v-html="vHtml" />
方法,这里注意引入的是mammoth.browser,算是一个坑吧
import * as mammoth from 'mammoth/mammoth.browser'
const getWord = (event) => {
const xhr = new XMLHttpRequest()
xhr.open('get', event, true)
xhr.responseType = 'arraybuffer'
xhr.onload = function() {
if (xhr.status === 200) {
mammoth
.convertToHtml({ arrayBuffer: new Uint8Array(xhr.response) })
.then((resultObject) => {
nextTick(() => {
vHtml.value = resultObject.value
})
})
}
}
xhr.send()
}
调用
getWord(word地址)