【问题标题】:TinyMCE display as A4TinyMCE 显示为 A4
【发布时间】:2015-07-01 22:14:56
【问题描述】:

我的网站上有一个 TinyMCE 编辑器,我希望以 A4 格式显示可编辑区域(或整个内容)。

基本上,我想以与在 MS Word 中相同的方式查看文档。 (宽度、分页符等)

这可能吗?请指出正确的方向。

【问题讨论】:

标签: javascript tinymce tinymce-4


【解决方案1】:

每个人都说这很难,但 Google 已经在 Google Docs 中做到了(提示:您可以使用 Google API,甚至可以获取文档的 PDF 版本。我没有这样做,因为我们编辑器中需要额外的功能。)

这是我的解决方案:

  1. 我已将页面大小调整为 A4 宽度
  2. 添加了一个标尺,显示还剩多少页(显然不是 100% 可靠,但很接近)。甚至页码!是的!

想法:

Ruler 比尝试显示每个页面要容易得多,这意味着拆分内容...虽然它会很糟糕...即使使用 css 剪辑,我也尝试过完整的 A4 页面,但它是弄乱了文本选择,所以我不知道...我希望我能做到,但是...

我在 HTML 标签中使用 SVG 的原因是因为它是我唯一可以放在那里的东西...如果您选择 TinyMCE 中的所有文本,您可以擦除我的标尺,甚至复制和粘贴...即使您使用 contenteditable ="false"...选择有限。

在这里查看我的解决方案:

https://jsfiddle.net/mzvarik/59smpdv8/

// plugin pravítko
    tinymce.PluginManager.add('ruler', function(editor) {

        var domHtml;
        var lastPageBreaks;

        function refreshRuler()
        {
  console.log("ddd");
            try {
        domHtml = $( editor.getDoc().getElementsByTagName('HTML')[0] );

       // HACK - erase this, I have to put my CSS here
       console.log($('tinystyle').html() );
       domHtml.find('head').append( $('<style>'+$('tinystyle').html()+'</style>'));

            } catch (e) {
                return setTimeout(refreshRuler, 50);
            }

            var dpi = 96
            var cm = dpi/2.54;
            var a4px = cm * (29.7-5.7); // A4 height in px, -5.5 are my additional margins in my PDF print

            // ruler begins (in px)
            var startMargin = 4;

            // max size (in px) = document size + extra to be sure, idk, the height is too small for some reason
            var imgH = domHtml.height() + a4px*5;

            var pageBreakHeight = 14; // height of the pagebreak line in tinyMce

            var pageBreaks = [];
            domHtml.find('.mce-pagebreak').each(function(){
                pageBreaks[pageBreaks.length] = $(this).offset().top;
            });
            pageBreaks.sort();

            // if pageBreak is too close next page, then ignore it

            if (lastPageBreaks == pageBreaks) {
                return; // no change
            }
            lastPageBreaks = pageBreaks;

            console.log("Redraw ruler");

            var s = '';
            s+= '<svg width="100%" height="'+imgH+'" xmlns="http://www.w3.org/2000/svg">';

            s+= '<style>';
            s+= '.pageNumber{font-weight:bold;font-size:19px;font-family:verdana;text-shadow:1px 1px 1px rgba(0,0,0,.6);}';
            s+= '</style>';

            var pages = Math.ceil(imgH/a4px);

            var i, j, curY = startMargin;
            for (i=0; i<pages; i++)
            {
                var blockH = a4px;

                var isPageBreak = 0;
                for (var j=0; j<pageBreaks.length; j++) {
                    if (pageBreaks[j] < curY + blockH) {
                        // musime zmensit velikost stranky
                        blockH = pageBreaks[j] - curY;
                        // pagebreak prijde na konec stranky
                        isPageBreak = 1;
                        pageBreaks.splice(j, 1);
                    }
                }

                s+= '<line x1="0" y1="'+curY+'" x2="100%" y2="'+curY+'" stroke-width="1" stroke="red"/>';

                // zacneme pravitko
                s+= '<pattern id="ruler'+i+'" x="0" y="'+curY+'" width="37.79527559055118" height="37.79527559055118" patternUnits="userSpaceOnUse">';
                s+= '<line x1="0" y1="0" x2="100%" y2="0" stroke-width="1" stroke="black"/>';
                s+= '</pattern>';
                s+= '<rect x="0" y="'+curY+'" width="100%" height="'+blockH+'" fill="url(#ruler'+i+')" />';

                // napiseme cislo strany
                s+= '<text x="10" y="'+(curY+19+5)+'" class="pageNumber" fill="#ffffff">'+(i+1)+'.</text>';

                curY+= blockH;
                if (isPageBreak) {
                    //s+= '<rect x="0" y="'+curY+'" width="100%" height="'+pageBreakHeight+'" fill="#FFFFFF" />';
                    curY+= pageBreakHeight;
                }
            }

            s+= '</svg>';

            domHtml.css('background-image', 'url("data:image/svg+xml;utf8,'+encodeURIComponent(s)+'")');
        }
        editor.on('NodeChange', refreshRuler);
        editor.on("init", refreshRuler);

    });

tinymce.init({
plugins: "ruler pagebreak",
toolbar1: "pagebreak",
selector: 'textarea',
height: 300
});

顺便说一句。 想象一下 Google 会制作免费的富文本编辑器!

CKEditor 也做不来还要付费,可惜了!

【讨论】:

    【解决方案2】:

    这是可能的,但很难,容易出错,而且你不会接近 MS Word。也许你可以用一种左右的字体来调整它。

    您需要做的是custom CSS 和custom template。模板应该类似于带有白色页面的灰色背景(带有阴影:)。使用 Javascript 定义一些将自定义类添加到模板的按钮,您将获得边距设置(窄、宽、正常、无值)。对于分页符,您可以插入一个特殊的&lt;hr&gt; 来设置底层页面模板的样式,就好像它结束而另一个开始一样。请记住,您必须替换几乎所有自定义 CSS 才能使其可以打印。另外,您应该让 tinymce 全屏显示。

    我见过的另一种(非常奇怪的)方法是 tinymce 和 PDF renderer library 或同等文件的组合。这样您就可以正确地获得所见即所得。

    希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      我修改了马丁的尺子。谢谢

      // plugin pravítko, modified by SerhatSoylemez
      tinymce.PluginManager.add("editor-ruler", function(editor) {
      
        var domHtml;
        var lastPageBreaks;
        var pagen= tinymce.util.I18n.translate("p.");
      
        function refreshRuler() {
          try {
            domHtml = $(editor.getDoc().getElementsByTagName('HTML')[0]);
          } catch (e) {
            return setTimeout(refreshRuler, 50);
          }
      
          var dpi = 96
          var cm = dpi/2.54;
          var a4px = cm * (29.7); // A4 height in px, -5.5 are my additional margins in my PDF print
      
          // ruler begins (in px)
          var startMargin = 0;
      
          // max size (in px) = document size + extra to be sure, idk, the height is too small for some reason
          var imgH = domHtml.height() + a4px*5;
      
          var pageBreakHeight = 4; // height of the pagebreak line in tinyMce
      
          var pageBreaks = [];  // I changed .mce-pagebreak with .page-break !!!
          domHtml.find('.page-break').each(function() {
            pageBreaks[pageBreaks.length] = $(this).offset().top;
          });
      
          pageBreaks.sort();
      
          // if pageBreak is too close next page, then ignore it
          if (lastPageBreaks == pageBreaks) {
            return; // no change
          }
      
          lastPageBreaks = pageBreaks;
      
          // console.log("Redraw ruler");
      
          var s = '';
          s+= '<svg width="100%" height="'+imgH+'" xmlns="http://www.w3.org/2000/svg">';
      
          s+= '<style>';
          s+= '.pageNumber{font-weight:bold;font-size:20px;font-family:verdana;text-shadow:1px 1px 1px rgba(0,0,0,.6);}';
          s+= '</style>';
      
          var pages = Math.ceil(imgH/a4px);
      
          var i, j, curY = startMargin;
          for (i=0; i<pages; i++) {
            var blockH = a4px;
      
            var isPageBreak = 0;
            for (var j=0; j<pageBreaks.length; j++) {
              if (pageBreaks[j] < curY + blockH) {
      
                // musime zmensit velikost stranky
                blockH = pageBreaks[j] - curY;
      
                // pagebreak prijde na konec stranky
                isPageBreak = 1;
                pageBreaks.splice(j, 1);
              }
            }
      
            curY2 = curY+38;
            s+= '<line x1="0" y1="'+curY2+'" x2="100%" y2="'+curY2+'" stroke-width="1" stroke="red"/>';
      
            // zacneme pravitko
            s+= '<pattern id="ruler'+i+'" x="0" y="'+curY+'" width="37.79527559055118" height="37.79527559055118" patternUnits="userSpaceOnUse">';
            s+= '<line x1="0" y1="0" x2="100%" y2="0" stroke-width="1" stroke="black"/>';
            s+= '<line x1="24" y1="0" x2="0" y2="100%" stroke-width="1" stroke="black"/>';
            s+= '</pattern>';
            s+= '<rect x="0" y="'+curY+'" width="100%" height="'+blockH+'" fill="url(#ruler'+i+')" />';
      
            // napiseme cislo strany
            s+= '<text x="10" y="'+(curY2+19+5)+'" class="pageNumber" fill="#e03e2d">'+pagen+(i+1)+'.</text>';
      
            curY+= blockH;
            if (isPageBreak) {
              //s+= '<rect x="0" y="'+curY+'" width="100%" height="'+pageBreakHeight+'" fill="#ffffff" />';
              curY+= pageBreakHeight;
            }
          }
      
          s+= '</svg>';
      
          domHtml.css('background-image', 'url("data:image/svg+xml;utf8,'+encodeURIComponent(s)+'")');
        }
      
        function deleteRuler() {
      
          domHtml.css('background-image', '');
        }
      
        var toggleState = false;
      
        editor.on("NodeChange", function () {
          if (toggleState == true) {
            refreshRuler();
          }
        });
      
      
        editor.on("init", function () {
          if (toggleState == true) {
            refreshRuler();
          }
        });
      
        editor.ui.registry.addIcon("square_foot", '<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24" viewBox="0 0 24 24" width="24">'+
        '<g><rect fill="none" height="24" width="24"/></g><g><g><path d="M17.66,17.66l-1.06,1.06l-0.71-0.71l1.06-1.06l-1.94-1.94l-1.06,1.06l-0.71-0.71'+
        'l1.06-1.06l-1.94-1.94l-1.06,1.06 l-0.71-0.71l1.06-1.06L9.7,9.7l-1.06,1.06l-0.71-0.71l1.06-1.06L7.05,7.05L5.99,8.11L5.28,7.4l1.06-1.06L4,4'+
        'v14c0,1.1,0.9,2,2,2 h14L17.66,17.66z M7,17v-5.76L12.76,17H7z"/></g></g></svg>');
      
        editor.ui.registry.addToggleMenuItem("ruler", {
          text: "Show ruler",
          icon: "square_foot",
          onAction: function() {
            toggleState = !toggleState;
            if (toggleState == false) {
              deleteRuler();
            } else {
              refreshRuler();
            }
          },
          onSetup: function(api) {
            api.setActive(toggleState);
            return function() {};
          }
        });
      
      });
      
      function loadJavascript(url) {
          var script = document.createElement("script");
          script.src = url;
          document.head.appendChild(script);
      }
      loadJavascript("https://code.jquery.com/jquery-3.5.1.min.js");
      

      【讨论】:

      • 嘿,感谢分享这个,但是当我初始化一个新的 tinymce 实例时,插件似乎没有加载。有什么帮助吗?
      猜你喜欢
      • 2017-08-08
      • 2020-01-17
      • 1970-01-01
      • 2021-05-19
      • 2015-01-10
      • 2019-04-18
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多