网站设计个人,手机怎样用网站做成软件,阿里云建网站教程,大气全屏通用企业网站整站源码预览文件 1、入口文件preview/index.vue2、预览txt3、预览doc4、预览pdf5、预览pptx6、预览xlsx7、预览csv 1、入口文件preview/index.vue
预览样式#xff0c;如pdf
文件目录如图所示#xff1a; 代码如下
templatediv classpreview-wrap ref如pdf
文件目录如图所示 代码如下
templatediv classpreview-wrap refpreviewDom v-ifhasPreviewFlagDocxPreview v-iffileType docx || fileType doc :file-datafileData /PdfPreview v-else-iffileType pdf :file-datafileData /TxtPreview v-else-iffileType txt :file-datafileData /XlsxPreview v-else-iffileType xlsx :file-datafileData /PptxPreview v-else-iffileType pptx :file-datafileData :file-idrow.id/CsvPreview v-else-iffileType csv :file-datafileData file-typecsv /div v-elseel-resulticonerrortitle提示sub-title文件不存在或者异常//div/div
/templatescript setup
import { ElMessage } from element-plus
import DocxPreview from ./components/DocxPreview.vue
import PdfPreview from ./components/PdfPreview.vue
import TxtPreview from ./components/TxtPreview.vue
import XlsxPreview from ./components/XlsxPreview.vue
import PptxPreview from ./components/PptxPreview.vue
import CsvPreview from ./components/CsvPreview.vue
import { ref, onMounted, defineProps } from vueconst props defineProps({row: {type: Object,default: () {},},
})
const filePath ref()
const fileType ref()
const fileData ref(null)
const hasPreviewFlag ref(true)onMounted(() {// console.log(row, props.row)const typeList [docx, doc, txt, pdf, xlsx, pptx, csv] // 目前支持的类型filePath.value props.row.cached_file_path || filePath.value D:\\work\\test.txt || props.row // 调试用// filePath.value D:\\work\\test.docx || props.row// filePath.value D:\\work\\test.xlsx || props.row// filePath.value D:\\work\\test.csv || props.row// filePath.value D:\\work\\test.pdf || props.row// filePath.value D:\\work\\test.pptxfileType.value (filePath.value.split(.).pop() || props.row.file_type).toLowerCase()if (!typeList.includes(fileType.value)) {return ElMessage.error(此文件不支持预览)}if (typeList.includes(fileType.value)) {hasPreviewFlag.value truewindow.electronAPI?.readFileSend(filePath.value) // 通过绝对路径获取文件流信息} else {hasPreviewFlag.value false}
})
// 这里根据客户端的主进程和渲染进行通过文件的绝对路径获取文件流
window.electronAPI?.readFileReceive((event, data) {// console.log(arraybuffer----, data) // 将arraybuffer转换成bolb形式fileData.value new Blob([data])
})
/scriptstyle langscss
.preview-wrap {height: calc(100vh - 130px);overflow: auto;z-index: 1;position: relative;padding: 8px;background: white;border: 1px solid #ccc;
}::-webkit-scrollbar {width: 0 !important;
}::-webkit-scrollbar {width: 0 !important;height: 0;
}
/style
preload.js // 跨窗口通信方法-读取文件readFileSend: (...args) ipcRenderer.send(read-file, ...args),readFileReceive: (cb) ipcRenderer.on(read-file, cb),main.js
// 通过文件的绝对路径获取文件流
ipcMain.on(read-file, (event, filePath) {const currentWindow BrowserWindow.fromWebContents(event.sender)fs.readFile(filePath, (err, res) {if (err) {console.log(read-file, err)} else { currentWindow currentWindow.webContents.send(read-file, res)}})
})2、预览txt
templatedivpre classtxtViewer{{ txtContent }}/pre/div
/templatescript setup
import { ref, watch, toRefs, defineProps } from vueconst props defineProps({fileData: {type: Blob,default: null}
})
const { fileData } toRefs(props)
const txtContent ref()watch(() fileData.value,(newv, oldv) {previewFile(newv)}
)
const previewFile fileData {const reader new FileReader();reader.onload () {txtContent.value reader.result;};reader.readAsText(fileData);
}/scriptstyle langscss scoped
.txtViewer {width: 100%;height: 100%;overflow: auto;margin-bottom: 0;white-space: pre-wrap;
}
/style
3、预览doc
采用docx-preview
templatedivdiv iddocx-content-preview classdocFile v-show!loading/div/div
/templatescript setup
import { renderAsync } from docx-preview
import { ref, defineProps, watch, toRefs } from vueconst loading ref(true)
const props defineProps({fileData: {type: Object,default: () {},},
})const { fileData } toRefs(props);watch(() fileData.value,val {loading.value truepreviewfile(val)},{ deep: true }
)
function previewfile(fileData) {// 选择要渲染的元素const docFile document.getElementsByClassName(docFile)// const blob new Blob([fileData])// 用docx-preview渲染renderAsync(fileData, docFile[0]).then(res {console.log(res----, res)loading.value false})
}
/scriptstyle langscss scoped
#docx-content-preview {min-height: 200px;overflow-x: hidden;padding: 10px;
}
.docFile {:deep(.docx-wrapper) {background: white;}:deep(section) {width: 100% !important;box-shadow: none;}
}:deep(.docx-wrapper section.docx) {width: 100% !important;padding: 0rem !important;min-height: auto !important;box-shadow: none;margin-bottom: 0;article {overflow: auto;}
}
/style
4、预览pdf
实现的方式有多种可采用pdfjs-dist、或 pdf.worker.min.mj可在官网上下载
templatediv styleposition:relative;div styletext-align: center; position: relative refpdfViewer classpdfViewer/div/div
/templatescript setup
import * as pdfjsLib from pdfjs-dist
import { ref, watch, toRefs } from vue
pdfjsLib.GlobalWorkerOptions.workerSrc ./pdf.worker.min.mjs;const props defineProps({fileData: {type: Blob,default: null}
})
const { fileData } toRefs(props);
const pdfViewer ref()
const loading ref(true)
const allParagraphs ref([])
const canvasHistory ref({})
// const scale 1.5
const scale window.devicePixelRatio 1.3 ? 1 : 1.5watch(() fileData.value,async (newVal, oldVal) {clearRec();previewFile(newVal)},{ deep: true }
)const previewFile (fileData) {getUint8ArrayData(fileData).then((uint8Array) {renderPdf(uint8Array)})
}const getUint8ArrayData (blob) {return new Promise((resolve, reject) {// 使用FileReader读取Blob对象const fileReader new FileReader()fileReader.onload function () {// 读取完成后result属性将包含Uint8Array数据const uint8Array new Uint8Array(fileReader.result)resolve(uint8Array)}fileReader.onerror function () {console.error(读取Blob时发生错误)reject(new Error(读取Blob时发生错误))}// 开始读取BlobfileReader.readAsArrayBuffer(blob)})
}
const renderPdf async (uint8Array) {const loadingTask pdfjsLib.getDocument(uint8Array)const pdf await loadingTask.promisefor (let i 1; i pdf.numPages; i) {await renderPage(pdf, i)}loading.value false;
}const renderPage async (pdf, pageNumber) {// 构造canvasconst canvas document.createElement(canvas)canvas.style direction: ltr;position: relativecanvas.id canvas_page_${pageNumber}canvas.className canvas_page// 构造文本层const layerDiv document.createElement(div)layerDiv.style position: absolute;left: 0;top: 0;right: 0;bottom: 0;overflow: hidden;opacity: 0.4;line-height: 1.0;layerDiv.id canvas_layer_page_${pageNumber}layerDiv.className canvas-layerconst div document.createElement(div)div.style width: fit-content;margin: 0 auto;position:relative; border: 1px solid #ccc; margin-bottom: 8px;div.id page-container-${pageNumber}div.className page-containerdiv.appendChild(canvas)// div.appendChild(layerDiv)pdfViewer.value.appendChild(div)const page await pdf.getPage(pageNumber)const viewport page.getViewport({ scale })// Support HiDPI-screens.const outputScale window.devicePixelRatio || 1// Prepare canvas using PDF page dimensionsconst context canvas.getContext(2d)canvas.width Math.floor(viewport.width * outputScale)canvas.height Math.floor(viewport.height * outputScale)canvas.style.width Math.floor(viewport.width) pxcanvas.style.height Math.floor(viewport.height) pxcanvas.style.maxWidth 1200 px // 解决pdf文档宽度过长导致样式错乱const transform outputScale ! 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null// Render PDF page into canvas contextconst renderContext {canvasContext: context,transform,viewport,}await page.render(renderContext).promise// 存入画布渲染pdf的状态用于还原canvasHistory.value[pageNumber] canvas.toDataURL()const textContent await page.getTextContent()// Pass the data to the method for rendering of text over the pdf canvas.// const task pdfjsLib.renderTextLayer({// textContentSource: page.streamTextContent(),// container: layerDiv,// viewport,// textDivs: [],// })// await task.promise// 处理得到每页的paragraphconst pageParagraphs handleParagraphs(pageNumber,canvas,viewport,textContent.items)await clearRec()allParagraphs.value allParagraphs.value.concat(pageParagraphs)
}const handleParagraphs (pageNumber, canvas, viewport, textContent) {const newArr groupByTransform(pageNumber,(textContent || []).filter((item) !!item.str.trim()))const paragraphs newArr.map((item) {return {pageNumber,canvas,viewport,content: item.map((it) it.str).reduce((a, b) {return a b}, ),items: item,}})return paragraphs
}
const groupByTransform (pageNumber, array) {const result []const map new Map()array.forEach((obj) {const key obj.transform[5]if (!map.has(key)) {map.set(key, [obj])} else {map.get(key).push(obj)}})map.forEach((value) {result.push(value)})return result
}
const clearRec async () {for (const key in canvasHistory.value) {const canvas document.getElementById(canvas_page_${key})if (canvas) {const context canvas.getContext(2d);const canvasPic await loadPdfImage(key)context.drawImage(canvasPic, 0, 0);} else {console.log(获取节点失败, canvas_page_${key})}}
}const loadPdfImage (index) {return new Promise((resolve, reject) {const canvasPic new Image();canvasPic.src canvasHistory.value[index]canvasPic.onload () {// 当图像加载完成后进行resolve,确保drawImage执行成功resolve(canvasPic)}canvasPic.onerror () {reject(new Error(加载还原图像失败))}})
}
/scriptstyle langscss scoped
.pdfViewer {min-height: 100%;:deep(.canvas-layer span) {color: transparent;position: absolute;white-space: pre;cursor: text;transform-origin: 0% 0%;background: transparent;z-index: 1;}:deep(.page-container) {width: 100% !important;.canvas_page {width: 100% !important;height: 100% !important;}}
}
/style5、预览pptx
6、预览xlsx
7、预览csv