pdf、markdown、docx文件预览
記錄一下實現 .md \ .pdf \ .docx文件的預覽。
markdown 文件預覽
安裝 markdown-it
$> npm install --save markdown-it解析.md文件轉換為 html,然后添加到 dom 節點中。
import MarkdownIt from "markdown-it";function parseFile(fileUrl) {// 創建實例const md = new MarkdownIt({html: true, // Enable HTML tags in sourcexhtmlOut: false, // Use '/' to close single tags (<br />).// This is only for full CommonMark compatibility.breaks: false, // Convert '\n' in paragraphs into <br>langPrefix: "language-", // CSS language prefix for fenced blocks. Can be// useful for external highlighters.linkify: false, // Autoconvert URL-like text to links// Enable some language-neutral replacement + quotes beautification// For the full list of replacements, see https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.jstypographer: false,// Double + single quotes replacement pairs, when typographer enabled,// and smartquotes on. Could be either a String or an Array.//// For example, you can use '???“' for Russian, '?“?‘' for German,// and ['?\xA0', '\xA0?', '?\xA0', '\xA0?'] for French (including nbsp).quotes: "“”‘’",});// 解析文件const html = md.render(fileUrl);return html; }拿到轉換后的 html,插入到 dom 節點中,這里給一個 vue 的示例
<template><div class="md-preview"><div class="content"><div className="markdown-content" v-html="content" /></div></div> </template> <script> import { onMounted, ref, computed } from "vue"; // md import ReadME from "@/README.md?raw";// 解析后的內容變量 const content = ref("");onMounted(() => {//content = parseFile(ReadME); }); </script>highlight.js 代碼高亮
解析出來的內容沒有任何樣式,通常我們的代碼使用高亮,方便閱讀。
安裝
$> npm install highlight.js通過屬性highlight定義需要處理的代碼片段
const md = new MarkdownIt({// ...highlight: (str, lang) => {if (lang && hljs.getLanguage(lang)) {try {return ('<pre class="hljs"><code>' +hljs.highlight(str, {language: lang,ignoreIllegals: true,}).value +"</code></pre>");} catch (__) {}}return ('<pre class="hljs"><code>' + md.utils.escapeHtml(str) + "</code></pre>");}, });此時只加了基本的樣式,可以通過導入不同主題的.css文件,來應用樣式。主題文件目錄highlight.js/styles/**
在頂部導入樣式文件,
import "highlight.js/styles/atom-one-dark.css";markdown-it-anchor 增加導航標識
通過標題導航到指定的文字,通常# 會被轉換為h . 通過配置增加永久性導航設置
安裝
@sindresorhus/slugify 用來處理獲取到的文本內容,有時候我們的標題中會含有一些特殊字符。能很好的處理
$> npm install markdown-it-anchor @sindresorhus/slugify --saveMarkdownIt 通過 use 方法安裝插件,
import MarkdownItAnchor from "markdown-it-anchor"; import slugify from "@sindresorhus/slugify";const md = new MarkdownIt({// ... }); md.use(MarkdownItAnchor, {level: 1,slugify: (s) => {return slugify(s);},getTokensText(tokens) {return tokens.filter((t) => ["text", "code_inline"].includes(t.type)).map((t) => t.content).join("");}, });可以看到轉換后的 html 內容中,所有的標題都包含有 id 屬性,通過permalink 生成永久性導航鏈接,
md.use(MarkdownItAnchor, {// ...permalink: MarkdownItAnchor.permalink.headerLink(), });可以在生成的 html 中看到h標題中有<a class="header-anchor" href="#title"></a>
node-html-parser 生成簡單 dom 結構,支持 query 節點
在轉換后的 html 中已經包含了可導航的標題信息;再從中提取出標題數據,即可自定義渲染導航菜單。
$> npm install node-html-parser --save以 vue 代碼示例
import { parse } from "node-html-parser";// 通過計算屬性,等待md文件解析完后生成對應的導航數據 const navData = computed(() => {const root = parse(content.value);const match = [];for (const h of root.querySelectorAll("h1, h2, h3, h4, h5, h6")) {const slug = h.getAttribute("id") || slugify(h.textContent);h.setAttribute("id", slug);// h.innerHTML = `<a href="#${slug}>${h.innerHTML}</a>`match.push(`<a href="#${slug}" class="${h.rawTagName}">${h.innerHTML}</a>`);}return match.join(""); });pdf 文件預覽
加載 pdf 文件,進行預覽。
安裝
$> npm install pdfjs-dist --savevue3 中沒有 require,所以安裝其他依賴
# 支持es module $> npm install @bundled-es-modules/pdfjs-dist通過讀取.pdf文件內容,繪制到 canvas 中,在家動態生成的 canvas 節點添加到指定區域。
import pdfjs from "@bundled-es-modules/pdfjs-dist/build/pdf"; // import viewer from '@bundled-es-modules/pdfjs-dist/web/pdf_viewer'; import worker from "@bundled-es-modules/pdfjs-dist/build/pdf.worker.js?url";pdfjs.GlobalWorkerOptions.workerSrc = worker;function parsePdf(fileUrl) {const self = this;// 創建實例,加載文件const loadingTask = pdfjs.getDocument(fileUrl);// container box ref 引用const container = this.$refs.pdf;// 通過promise讀取loadingTask.promise.then(function (doc) {const numPages = doc.numPages;// meta 數據信息doc.getMetadata().then(function (data) {// 元數據信息});const loadPage = function (pageNum) {doc.getPage(pageNum).then(function (page) {const scale = 1;const viewport = page.getViewport({ scale });const outputScale = window.devicePixelRatio || 1;const canvas = document.createElement("canvas");const context = canvas.getContext("2d");// contianer 為預覽所在的dom區域container.appendChild(canvas);canvas.width = Math.floor(viewport.width * outputScale);canvas.height = Math.floor(viewport.height * outputScale);canvas.style.width = Math.floor(viewport.width) + "px";canvas.style.height = Math.floor(viewport.height) + "px";const transform =outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;const renderContext = {canvasContext: context,transform,viewport,};page.render(renderContext);});};for (let i = 1; i <= numPages; i++) {// 加載讀取每一頁數據loadPage(i);}}); }那對應的 vue 示例,
<template><div class="pdf-preview"><div ref="pdf" /></div> </template>docx文件預覽
加載 docx 文件數據流轉換為 html,然后插入 dom 節點中
安裝
$> npm install mammoth --save瀏覽器使用引用的是mammoth/mammoth.browser,需要的數據格式必須是ArrayBuffer
示例是加載本地項目總的資源,通過網絡請求加在資源為數據流blob,然后通過FileReader轉換為 ArrayBuffer
此處以 vue 示例
<template><div class="docx-preview"><div ref="docx" v-html="content" /></div> </template> <script setup> import mammoth from 'mammoth/mammoth.browser' import { ref } from 'vue'const conent = ref('')function parseDocs(fileUrl){let $this = this// raadfileconst blob = await this.$http.request({type: 'get',url: fileUrl,responseType: 'blob',})// blob 轉 arrayBufferconst fileReader = new FileReader()fileReader.onload = function (res) {// 解析轉換mammoth.convertToHtml({ arrayBuffer: fileReader.result }).then(function (result) {const html = result.value // The generated HTML$this.content = html}).done()}fileReader.readAsArrayBuffer(blob) } <script>.docx只解析為 html,沒有任何樣式,需要自己去設置樣式。所以說如果就只是預覽,可以讓后端轉為 pdf 后前端在展示預覽。
具體實例代碼可參考示例項目:
vite+vue3 模板代碼倉庫(vite-vue3)[https://gitee.com/ngd_b/vue3-vite]
總結
以上是生活随笔為你收集整理的pdf、markdown、docx文件预览的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Access数据库压缩失败后修复经历
- 下一篇: 反省文+日后计划