Vue富文本编辑器Tinymce内容导出Pdf、Word

2023-05-16

一、Tinymce导出Pdf

使用VueHtml2pdf插件,安装插件,VueHtml2pdf详情见vue-html2pdf - npm

npm i VueHtml2pdf

引入和注册

// 引入
import VueHtml2pdf from 'vue-html2pdf'
// 注册
components: {
  VueHtml2pdf,
},

html部分

<vue-html2pdf
  :show-layout="false"
  :float-layout="true"
  :enable-download="true"
  :preview-modal="false"
  :paginate-elements-by-height="1400"
  :filename="tempFileName"
  :pdf-quality="2"
  :manual-pagination="false"
  pdf-format="a4"
  pdf-orientation="landscape"
  pdf-content-width="800px"
  @progress="onProgress($event)"
  @hasStartedGeneration="hasStartedGeneration()"
  @hasGenerated="hasGenerated($event)"
  ref="html2Pdf"
>
  <section slot="pdf-content">
    <!-- PDF Content Here -->
    <span id="report" v-html="content"></span>
  </section>
</vue-html2pdf>

<Tinymce ref="tinymce" v-model="content" :id="id" />

<!--按钮-->
<el-button type="primary" @click="handleSaveToPdf">保存为Pdf</el-button>
<el-button type="primary" @click="handleSaveToWord">保存为Word</el-button>

js

 handleSaveToPdf() {
   this.$refs.html2Pdf.generatePdf()
 },
 onProgress() {

 },
 hasStartedGeneration() {

 },
 hasGenerated() {

 },

二、Tinymce导出Word

1. html生成doc文件

准备三个文件jquery.js,FileSaver.js,jquery.wordexport.js,前两个可以通过cdn拿到,jquery.wordexport.js通过https://github.com/markswindoll/jQuery-Word-Export#readme下载,将这三个文件放在public/static文件夹下,在public的index.html中引入

jquery.wordexport.js全部代码如下:

if (typeof jQuery !== "undefined" && typeof saveAs !== "undefined") {
  (function ($) {
    $.fn.wordExport = function (fileName) {
      fileName = typeof fileName !== "undefined" ? fileName : "jQuery-Word-Export";
      var staticObj = {
        mhtml: {
          top:
            "Mime-Version: 1.0\nContent-Base: " +
            location.href +
            '\nContent-Type: Multipart/related; boundary="NEXT.ITEM-BOUNDARY";type="text/html"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset="utf-8"\nContent-Location: ' +
            location.href +
            "\n\n<!DOCTYPE html>\n<html>\n_html_</html>",
          head: '<head>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n<style>\n_styles_\n</style>\n</head>\n',
          body: "<body>_body_</body>",
        },
      };
      var options = {
        maxWidth: 624,
      };
      // Clone selected element before manipulating it
      var markup = $(this).clone();

      // Remove hidden elements from the output
      markup.each(function () {
        var self = $(this);
        if (self.is(":hidden")) self.remove();
      });

      // Embed all images using Data URLs
      var images = Array();
      var img = markup.find("img");
      for (var i = 0; i < img.length; i++) {
        // Calculate dimensions of output image
        var w = Math.min(img[i].width, options.maxWidth);
        var h = img[i].height * (w / img[i].width);
        // Create canvas for converting image to data URL
        var canvas = document.createElement("CANVAS");
        canvas.width = w;
        canvas.height = h;
        // Draw image to canvas
        var context = canvas.getContext("2d");
        context.drawImage(img[i], 0, 0, w, h);
        // Get data URL encoding of image
        var uri = canvas.toDataURL("image/png");
        $(img[i]).attr("src", img[i].src);
        img[i].width = w;
        img[i].height = h;
        // Save encoded image to array
        images[i] = {
          type: uri.substring(uri.indexOf(":") + 1, uri.indexOf(";")),
          encoding: uri.substring(uri.indexOf(";") + 1, uri.indexOf(",")),
          location: $(img[i]).attr("src"),
          data: uri.substring(uri.indexOf(",") + 1),
        };
      }

      // Prepare bottom of mhtml file with image data
      var mhtmlBottom = "\n";
      for (var i = 0; i < images.length; i++) {
        mhtmlBottom += "--NEXT.ITEM-BOUNDARY\n";
        mhtmlBottom += "Content-Location: " + images[i].location + "\n";
        mhtmlBottom += "Content-Type: " + images[i].type + "\n";
        mhtmlBottom +=
          "Content-Transfer-Encoding: " + images[i].encoding + "\n\n";
        mhtmlBottom += images[i].data + "\n\n";
      }
      mhtmlBottom += "--NEXT.ITEM-BOUNDARY--";

      //TODO: load css from included stylesheet
      var styles = "";

      // Aggregate parts of the file together
      var fileContent =
        staticObj.mhtml.top.replace(
          "_html_",
          staticObj.mhtml.head.replace("_styles_", styles) +
            staticObj.mhtml.body.replace("_body_", markup.html())
        ) + mhtmlBottom;

      // Create a Blob with the file contents
      var blob = new Blob([fileContent], {
        type: "application/msword;charset=utf-8",
      });
      saveAs(blob, fileName + ".doc");
    };
  })(jQuery);
} else {
  if (typeof jQuery === "undefined") {
    console.error("jQuery Word Export: missing dependency (jQuery)");
  }
  if (typeof saveAs === "undefined") {
    console.error("jQuery Word Export: missing dependency (FileSaver.js)");
  }
}
<!-- html导出生成word -->
<script src="./static/lib/htmlToWord/jquery.min.js"></script>
<script src="./static/lib/htmlToWord/FileSaver.min.js"></script>
<script src="./static/lib/htmlToWord/jquery.wordexport.js"></script>

在组件中直接调用就可以了,一下是js代码

handleSaveToWord() {
  $("#report").wordExport('模板'); //打印id为page的div中的所有内容
},

2. html 生成docx文件

准备FileSaver.min.js、html-docx.js这两个文件,html-docx.js详见

GitHub - evidenceprime/html-docx-js: Converts HTML documents to DOCX in the browser

<script src="./static/lib/htmlToWord/FileSaver.min.js"></script>
<script src="./static/lib/htmlToWord/html-docx.js"></script>

方法:

    handleSaveToWord() {
      var converted = htmlDocx.asBlob(this.content);
      saveAs(converted, 'test.docx');
    },

最后一定要在编辑器初始化中设置

initTinymce() {
      const _this = this
      window.tinymce.init({
        selector: `#${this.tinymceId}`,
        language: 'zh_CN',
        height: this.height,
        body_class: 'panel-body ',
        object_resizing: false,
        toolbar: this.tabbar,
        menubar:false,
        plugins: ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount charmap'],
        end_container_on_empty_block: true,
        powerpaste_word_import: 'clean',
        fontsize_formats: "8pt 10pt 11pt 12pt 14pt 18pt 24pt 36pt",
        code_dialog_height: 450,
        code_dialog_width: 1000,
        advlist_bullet_styles: 'circle,disc,square',
        advlist_number_styles: 'default',
        default_link_target: '_blank',
        link_title: false,
        nonbreaking_force_tab: true, 
        branding: false,
        readonly: this.readonly,
        init_instance_callback: editor => {
          if (_this.value) {
            console.log('_this.value',_this.value)
            editor.setContent(_this.value)
          }
          _this.hasInit = true
          // 用来触发获得内容
          editor.on('NodeChange Change KeyUp SetContent', () => {
            this.hasChange = true
            this.$emit('input', editor.getContent())
          })
        },
        setup(editor) {
          editor.on('FullscreenStateChanged', (e) => {
            _this.fullscreen = e.state
          })
        },
        convert_urls: false
      })
    },

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue富文本编辑器Tinymce内容导出Pdf、Word 的相关文章

随机推荐