Recently, there is a need to use the browser printing function in the business. I thought it was very simple, but the actual operation is not smooth, and there are many obstacles to achieve the expected effect, so I made a record.

directory

  • Based on brief introduction to
  • Several browser printing methods
    • A full page to print
    • Print custom components
  • Iframe Print bullet points
    • Iframe default style override
    • The height and width should be fixed
  • Print the page
  • Reference Code Example (VUE)

Based on brief introduction to

  • Core methodwindow.print()
  • After the call, a print preview page will pop up, and make the browser process into a waiting state, click the print or cancel button will continue to run the following code
  • You are advised to set a margin for printing to control the printing effect. After the first setting, the browser saves the setting
  • Printing paper size is actually a proportion, into A4 paper is the square root of two to one, as long as you control the ratio of the outermost layer of printing basically there will be no problem

Several browser printing methods

If you don’t want to skip the nonsense, the last method is to trigger printing with iframe without any visual changes to the page

A full page to print

  1. throughwindow.print()Print directly on the whole page
    • Will print the current entirewindow.documentCorresponding page
    • This method is the simplest and most useless, and basically fails to implement printing scenarios for various businesses

Print custom components

  • Inline styles are best used for custom components
  1. Print the custom component with window.print()

    • Start by getting the custom component content element
    • Save the current pagebodyUnder the wholehtml
    • Replace the custom component elementbodyThe elements of the
    • Perform print
    • Restore the original page after printing
    • This method will replace the current page with the printed page content, which may change visually and may not work for some scenarios
  2. Print custom components through window.open()

    • Start by getting the custom component content element that the component can usez-index: -9999; opacity: 0;And other methods are not displayed on the original page
    • uselet newWindow = window.open("",'newwindow', 'height=300, width=700, top=100, left=100, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=n o, status=no');Open a new window
    • Puts the custom component element content into the new windowbody
    • Perform print
    • Execute after printingnewWindow.close()Close new window
    • This method does not change the original page visual effect, but will pop up a new window, some scenes may not be suitable
  3. Print custom components through the backend URL

    • Retrieving custom component content from the back endURLRequest path
    • uselet newWindow = window.open(URL,'newwindow', 'height=300, width=700, top=100, left=100, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=n o, status=no');Open a new window
    • Perform print
    • Execute after printingnewWindow.close()Close new window
    • This approach is much the same as the previous one, except that retrieving custom component content elements has been moved from the front end to the back end, with the same drawbacks
  4. Print custom components using iframe

    • Start by getting the custom component content element that the component can usez-index: -9999; opacity: 0;And other methods are not displayed on the original page
    • addiframeElement that can be useddisplay: none;And other methods are not displayed on the original page
    • Puts custom component element content intoiframebody
    • Perform print
    • This approach should be as close as possible to triggering the print without any visual changes to the page, but there are a few caveats

Iframe Print bullet points

Iframe default style override

  • iframeIt’s like a new window, with built-in styles that are usually used in engineered pages todayreset.cssSuch means pull together various browser styles, so put components in the original page definitioniframeIs likely to behave inconsistently, so theiframeProblem style overrides
  • More common problem style (compare the effect of printing, take Google as an example) :
    • bodybuilt-inmargin: 8px;, you need to set the margin to 0
    • Box model problem, need in beltpaddingTo the element ofbox-sizing: border-box;
    • includingline-heightAnd so onH1, H2, P“Elements, pay attention to overwrite style or avoid using
  • Can also be the original page<head>All contents iniframe<head>In:iframe.document.head.innerHTML = document.head.innerHTML;This method is not applicable in some situations

The height and width should be fixed

  • Components written with a responsive layout usually do not use fixed widths, but firefox (not to the exclusion of other browsers) has them18px(even if you have rimless margins), this can cause firefox style confusion and requires a fixed width
  • Such asA4Paper printing, the height can be set to1122px, width is793.37 px.(Calculated based on a fixed ratio of square root of two to one)

Print the page

  • I just use itcssBut much of the content on the web is dated, and finding the right one took a while.
  • The test is valid,break-after: page;When printed, the element with this property is paginated after it is set

Reference Code Example (VUE)

<div class="cover-preview" v-if="showPreviewCover">
    <div id="print-cover-box" style="Width: 793.37 px; color: #000;">
        <! -- Firefox comes with 18px margins, even if it is set to infinity -->
        <div v-for="item in coverList" :key="item.objectId" style="break-after: page; width: 100%; height: 1122px; padding: 140px 80px; box-sizing: border-box;"> 
            <div style="width: 100%; height: 100%; border: 6px solid #000; padding: 6px; box-sizing: border-box;">
                <! -... -->
            </div>
        </div>
    </div>
</div>
<iframe id="print-cover-iframe" frameborder="0" style="display: none;"></iframe>
Copy the code
this.showPreviewCover = true;
this.$nextTick(() = > {
    let iframe = document.getElementById('print-cover-iframe').contentWindow;
    var printHtml = document.getElementById("print-cover-box").outerHTML;
    // iframe.document.head.innerHTML = document.head.innerHTML;
    iframe.document.body.style.margin = '0px';
    iframe.document.body.innerHTML = printHtml;
    iframe.print();
    this.showPreviewCover = false;
})
Copy the code
.cover-preview{
    position: absolute;
    left: 50%;
    top: 0;
    overflow: auto;
    transform: translateX(-50%);
    background-color: white;
    border-left: 1px solid # 333;
    border-right: 1px solid # 333;
    z-index: -9999;
    opacity: 0;
}
Copy the code