richTextPdf.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <!-- 富文本PDF预览与下载组件 (小程序版本) -->
  2. <template>
  3. <view class="rich-text-pdf-wrapper">
  4. <scroll-view scroll-y class="content-scroll">
  5. <view class="rich-content">
  6. <rich-text :nodes="content"></rich-text>
  7. </view>
  8. </scroll-view>
  9. </view>
  10. </template>
  11. <script>
  12. export default {
  13. name: 'RichTextPdf',
  14. props: {
  15. content: {
  16. type: String,
  17. default: ''
  18. }
  19. },
  20. data() {
  21. return {
  22. loading: false
  23. };
  24. },
  25. methods: {
  26. // 微信小程序版本:使用 Canvas 生成图片后保存
  27. async downloadPDF() {
  28. if (!this.content) {
  29. uni.showToast({
  30. title: '没有可下载的内容',
  31. icon: 'none'
  32. });
  33. return;
  34. }
  35. this.loading = true;
  36. uni.showLoading({ title: '生成中...' });
  37. try {
  38. // 由于小程序限制,这里使用简化方案:
  39. // 1. 将富文本内容通过截图保存为图片
  40. // 2. 或者直接保存HTML内容供后续查看
  41. // 方案1: 使用 Canvas 截图(需要配合后端或使用第三方服务)
  42. // 由于小程序无法直接将 rich-text 渲染到 canvas,
  43. // 这里采用保存为图片的简化方案
  44. await this._saveAsImage();
  45. } catch (error) {
  46. console.error('PDF 生成失败:', error);
  47. uni.showToast({
  48. title: 'PDF下载失败,请重试',
  49. icon: 'none'
  50. });
  51. } finally {
  52. this.loading = false;
  53. uni.hideLoading();
  54. }
  55. },
  56. // 简化方案:保存为图片
  57. async _saveAsImage() {
  58. // 微信小程序中,rich-text 无法直接转为 canvas
  59. // 需要使用以下方案之一:
  60. // 1. 后端生成PDF接口
  61. // 2. 使用 web-view 加载HTML后截图
  62. // 3. 提示用户长按保存或分享
  63. uni.showModal({
  64. title: '提示',
  65. content: '微信小程序暂不支持直接生成PDF,建议在电脑端下载或长按保存内容',
  66. showCancel: false
  67. });
  68. // 如果有后端PDF生成接口,可以这样调用:
  69. // const result = await this._callBackendPdfApi();
  70. // if (result.pdfUrl) {
  71. // uni.downloadFile({
  72. // url: result.pdfUrl,
  73. // success: (res) => {
  74. // uni.saveFile({
  75. // tempFilePath: res.tempFilePath,
  76. // success: () => {
  77. // uni.showToast({ title: '保存成功' });
  78. // }
  79. // });
  80. // }
  81. // });
  82. // }
  83. },
  84. // 调用后端PDF生成接口(示例)
  85. async _callBackendPdfApi() {
  86. return new Promise((resolve, reject) => {
  87. uni.request({
  88. url: '/api/generate-pdf', // 替换为实际接口
  89. method: 'POST',
  90. data: {
  91. htmlContent: this.content
  92. },
  93. success: (res) => {
  94. if (res.data.code === 200) {
  95. resolve(res.data.data);
  96. } else {
  97. reject(new Error(res.data.message));
  98. }
  99. },
  100. fail: reject
  101. });
  102. });
  103. }
  104. }
  105. };
  106. </script>
  107. <style lang="stylus" scoped>
  108. .rich-text-pdf-wrapper {
  109. width: 100%;
  110. height: 100%;
  111. display: flex;
  112. flex-direction: column;
  113. background: #fff;
  114. }
  115. .content-scroll {
  116. flex: 1;
  117. overflow: hidden;
  118. }
  119. .rich-content {
  120. padding: 40rpx;
  121. font-size: 28rpx;
  122. line-height: 1.8;
  123. color: #333;
  124. word-wrap: break-word;
  125. }
  126. </style>