renders.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * @Author: LiZhiWei
  3. * @Date: 2025-04-09 08:10:23
  4. * @LastEditors: LiZhiWei
  5. * @LastEditTime: 2025-04-15 14:47:12
  6. * @Description:
  7. */
  8. import { defaultOptions, renderAsync } from "docx-preview"
  9. import renderPdf from "./vendors/pdf"
  10. import renderImage from "./vendors/image"
  11. import renderText from "./vendors/text"
  12. import renderPptx from "./vendors/pptx"
  13. import renderSheet from "./vendors/xlsx"
  14. // 假装构造一个vue的包装,让上层统一处理销毁和替换节点
  15. const VueWrapper = (el) => ({
  16. $el: el,
  17. $destroy() {
  18. // 什么也不需要 nothing to do
  19. },
  20. })
  21. const handlers = [
  22. // 使用docxjs支持,目前效果最好的渲染器
  23. {
  24. accepts: ["docx"],
  25. handler: async (buffer, target) => {
  26. const docxOptions = {
  27. ...defaultOptions,
  28. ...{
  29. debug: true,
  30. experimental: true,
  31. },
  32. }
  33. await renderAsync(buffer, target, null, docxOptions)
  34. return VueWrapper(target)
  35. },
  36. },
  37. // 使用pptx2html,已通过默认值更替
  38. {
  39. accepts: ["pptx"],
  40. handler: async (buffer, target) => {
  41. return renderPptx(buffer, target)
  42. },
  43. },
  44. // 使用sheetjs + handsontable,无样式
  45. {
  46. accepts: ["xlsx"],
  47. handler: async (buffer, target) => {
  48. return renderSheet(buffer, target)
  49. },
  50. },
  51. // 使用pdfjs,渲染pdf,效果最好
  52. {
  53. accepts: ["pdf"],
  54. handler: async (buffer, target) => {
  55. return renderPdf(buffer, target)
  56. },
  57. },
  58. // 图片过滤器
  59. {
  60. accepts: ["gif", "jpg", "jpeg", "bmp", "tiff", "tif", "png", "svg"],
  61. handler: async (buffer, target) => {
  62. return renderImage(buffer, target)
  63. },
  64. },
  65. // 纯文本预览
  66. {
  67. accepts: [
  68. "txt",
  69. "json",
  70. "js",
  71. "css",
  72. "java",
  73. "py",
  74. "html",
  75. "jsx",
  76. "ts",
  77. "tsx",
  78. "xml",
  79. "md",
  80. "log",
  81. ],
  82. handler: async (buffer, target) => {
  83. return renderText(buffer, target)
  84. },
  85. },
  86. // 错误处理
  87. {
  88. accepts: ["error"],
  89. handler: async (buffer, target, type) => {
  90. target.innerHTML = `<div style="text-align: center margin-top: 80px">不支持.${type}格式的在线预览,请下载后预览或转换为支持的格式</div>
  91. <div style="text-align: center">支持docx, xlsx, pptx, pdf, 以及纯文本格式和各种图片格式的在线预览</div>`
  92. return VueWrapper(target)
  93. },
  94. },
  95. ]
  96. // 匹配
  97. export default handlers.reduce((result, { accepts, handler }) => {
  98. accepts.forEach((type) => (result[type] = handler))
  99. return result
  100. }, {})