editeDemo.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template>
  2. <div class="EditorTop">
  3. <Toolbar
  4. :editor="editorRef"
  5. :default-config="config.toolbarConfig"
  6. />
  7. </div>
  8. <div class="EditorContent">
  9. <div
  10. v-for="s in arrBr"
  11. :key="s"
  12. class="brs"
  13. :style="`top:${s * A4Height + 45}px`"
  14. >
  15. PDF分割线
  16. </div>
  17. <div class="resetStyle">
  18. <Editor
  19. id="exportPDF"
  20. v-model="valueHtml"
  21. :default-config="config.editorConfig"
  22. @onCreated="handleCreated"
  23. @onChange="changes"
  24. />
  25. </div>
  26. </div>
  27. </template>
  28. <script setup lang='ts'>
  29. import { onBeforeUnmount, ref, shallowRef } from 'vue'
  30. import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
  31. import '@wangeditor/editor/dist/css/style.css'
  32. // 编辑器实例,必须用 shallowRef,重要!
  33. const editorRef = shallowRef()
  34. // 配置模式及上传图片地址
  35. const config = {
  36. toolbarConfig: {
  37. toolbarKeys: [
  38. 'headerSelect',
  39. 'bold', 'underline', 'italic',
  40. 'clearStyle', 'color', 'bgColor',
  41. 'fontSize', 'fontFamily', 'justifyLeft',
  42. 'justifyRight', 'justifyCenter', 'justifyJustify',
  43. 'uploadImage', 'insertLink', 'insertTable',
  44. 'SaveBtn'
  45. ]
  46. },
  47. editorConfig: {
  48. placeholder: '请输入内容...',
  49. MENU_CONF: {
  50. uploadImage: {
  51. server: '/api/upload',
  52. withCredentials: true, // 跨域是否传递 cookie
  53. // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
  54. meta: {
  55. token: 'xxx'
  56. },
  57. allowedFileTypes: [ 'image/*' ],
  58. maxFileSize: 50 * 1024 * 1024, // 最大50M
  59. base64LimitSize: 20 * 1024 * 1024 // 小于20M就插入 base64 格式
  60. }
  61. }
  62. }
  63. }
  64. // 内容 HTML
  65. const value = (
  66. `<p style="text-indent: 42pt; text-align: left;"><span style="font-size: 19px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-size: 19px; font-family: 黑体;"> &nbsp;合同编号</span><span style="font-size: 19px; font-family: 黑体;"><u>xxx</u></span></p>
  67. <p style="text-indent: 42pt; text-align: left;"><span style="font-size: 19px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-size: 19px; font-family: 黑体;"> &nbsp;报告编号</span><span style="font-size: 19px; font-family: 黑体;"><u>xxx</u></span></p>
  68. <p style="text-indent: 42pt;"><br></p><p style="text-indent: 42pt;"><br></p><p style="text-indent: 42pt;"><br></p><p style="text-indent: 42pt;"><br></p><p style="text-indent: 42pt;"><br></p>
  69. <p style="text-indent: 42pt;"><br></p><p style="text-align: center;"><span style="font-size: 22px;">XXXtest</span></p>
  70. <p style="text-align: center;"><span style="font-size: 22px;">XXXtest</span></p><p style="text-align: center;"><br></p>
  71. <h4 style="text-align: center;"><span style="font-size: 48px;">test</span></h4>
  72. <p style="text-align: center;"><strong> </strong></p><p style="text-align: center;"><br></p>
  73. <p style="text-align: center;"><br></p><p style="text-align: center;"><span style="font-size: 19px; font-family: 黑体;"><strong>(2022.xx.xx~2022.xx.xx)</strong></span></p>
  74. <p style="text-align: center;"><span style="font-size: 22px;"><strong> </strong></span></p>
  75. <p style="text-align: center;"><br></p><p style="text-align: center;"><br></p>
  76. <p style="text-align: center;"><br></p><p style="text-align: center;"><br></p>
  77. <p style="text-align: center;"><br></p><p style="text-align: center;"><span style="color: rgb(0, 0, 0); font-size: 22px;">xxx单位</span></p>
  78. <p style="text-align: center;"><span style="color: rgb(0, 0, 0); font-size: 22px;">二零二二</span><span style="font-size: 22px;">年xx月xx</span><span style="color: rgb(0, 0, 0); font-size: 22px;">日</span></p>
  79. `
  80. ).replace(/[\r\n]/g, '')
  81. const valueHtml = ref(value)
  82. // A4 默认1228高度
  83. const A4Height = 1023
  84. // 分割线
  85. const arrBr = ref(0)
  86. // 编辑器回调函数
  87. const handleCreated = (editor: any) => {
  88. editorRef.value = editor // 记录 editor 实例,重要!
  89. }
  90. // 根据A4高度标识分割线条数
  91. const changes = (editor: any) => {
  92. const dom = editor.getEditableContainer() || null
  93. if (dom) {
  94. const num = Math.floor(dom.offsetHeight / A4Height)
  95. if (num !== arrBr.value) {
  96. arrBr.value = num
  97. }
  98. // 滚动到最底部
  99. const editContentDom = document.getElementsByClassName('EditorContent')[0] as HTMLElement
  100. editContentDom.scrollTo(0, dom.offsetHeight)
  101. }
  102. }
  103. // // 获取编辑后的数据
  104. // setTimeout(() => {
  105. // console.log('output->test', editorRef.value.getAllMenuKeys(), editorRef.value.getHtml())
  106. // }, 3000)
  107. // 组件销毁时,也及时销毁编辑器,重要!
  108. onBeforeUnmount(() => {
  109. const editor = editorRef.value
  110. if (editor == null) return
  111. editor.destroy()
  112. })
  113. </script>
  114. <style lang="less" scoped>
  115. .EditorTop {
  116. background: white;
  117. &>div {
  118. border-bottom: 1px solid #ccc;
  119. text-align: center;
  120. display: flex;
  121. align-items: center;
  122. justify-content: center;
  123. }
  124. }
  125. .EditorContent {
  126. height: 95%;
  127. background-color: rgb(245, 245, 245);
  128. overflow-y: scroll;
  129. position: relative;
  130. .resetStyle {
  131. width: 850px;
  132. margin: 30px auto;
  133. background-color: #fff;
  134. padding: 20px 50px 50px 50px;
  135. border: 1px solid #e8e8e8;
  136. box-shadow: 0 2px 10px rgb(0 0 0 / 12%);
  137. position: relative;
  138. z-index: 0;
  139. :deep(.w-e-text-container) {
  140. min-height: 600px;
  141. .w-e-scroll {
  142. min-height: 600px;
  143. }
  144. }
  145. }
  146. &::-webkit-scrollbar {
  147. display: block;
  148. width: 8px !important; //对垂直方向滚动条
  149. }
  150. //滚动的滑块
  151. &::-webkit-scrollbar-thumb {
  152. border-radius: 3px !important;
  153. background-color: #ccc !important; //滚动条的颜色
  154. }
  155. //内层滚动槽
  156. &::-webkit-scrollbar-track-piece {
  157. background-color: rgb(245, 245, 245) !important;
  158. }
  159. .brs {
  160. width: 100%;
  161. position: absolute;
  162. border-bottom: dashed 2px #ccc;
  163. color: #ccc;
  164. text-align: right;
  165. }
  166. }
  167. </style>