Search code examples
reactjstinymcepuppeteerprinting-web-page

How to keep TinyMCE Print styles when content is outside of the Editor


I'm attempting to print off the contents of a React TinyMCE Editor using an HTML to PDF converter, but when I extract the contents and set it in their own page the styling is very different. It retains some of the styling but not all of it.

If I press ctrl + p within the editor it works great and comes out styled as a document. But when I use puppeteer to print off the web page as a PDF, it prints off the full page including the wrapping content (toolbars, menu, etc.) and doesn't apply the nice default styling to the content.

I've tried extracting and displaying the content with something like the below:

import { useRef, useState } from "react"
import { Editor } from "@tinymce/tinymce-react"
import classNames from "classnames"

const TextEditor = (props) => {

   const ref = useRef(null);
   const [editorContent, setEditorContent] = useState(null);
   return <>
   {editorContent &&
      <div className="mce-content-body" dangerouslySetInnerHTML={{"__html": editorContent.innerHTML}}></div>
   }
   <form className={classNames([{"d-none": editorContent !== null}])}>
      <Editor
          tinymceScriptSrc={process.env.PUBLIC_URL + "/tinymce/tinymce.min.js"}
          onInit={(evt, editor) => {
             ref.current = editor;
             setEditorContent(ref.current.getBody());
          }}
          initialValue={props.initialContent}
          init={{
             height: "100%",
             menubar: true,
             plugins: ["print"],
             toolbar: "print",
             content_style: `
                body {
                    font-family: Verdana,Helvetica,Arial,sans-serif;
                    font-size: 12pt;
                }
                @media screen {
                    body {
                       padding-left: 1.4in;
                       padding-right: 1.4in;
                    }
                }
                @media print {
                   body {
                      padding-left: 0.8in;
                      padding-right: 0.8in;
                      caret-color: transparent;
                   }
                   @page {
                      margin-top: 0.75in;
                      margin-bottom: 0.75in;
                   }
                }
             `,
             content_css: "document"
          }}
      />
   </form>
<>
}

and I've played around with the classes for a bit to ensure I've added in the skin.min.css and content.min.css etc. but I still haven't been able to trick the browser into believing it should come out the same as if the user pressed Ctrl + P on the editor content.

Am I missing some hidden @media print {} or something like that to make the same style of printout?


Solution

  • It turns out my problem was that I had unintentionally left Bootstrap css in a HTML head style element. Bootstrap's @media print clashes with TinyMCE's print design. After taking out the Bootstrap css, I could then put in the necessary styles to make the printout the same as when printed from TinyMCE's iframed editor content.