繁体   English   中英

如何在浏览器中跨多个页面宽度打印大画布?

[英]How to print a large canvas across multiple page widths in browser?

我的应用程序需要打印出一个可以跨越多个页面宽度和高度宽度的任意大画布。

一段时间后有一个类似的问题,声称浏览器不会打印到多个页面宽度

由于这是一段时间,我想知道它是否仍然是真的。 另外,有哪些策略可以打印出大型画布而不将其拆分?

 var canvas = document.getElementById("canvas1"); function draw_a() { var context = canvas.getContext("2d"); // // LEVER //plane context.fillStyle = '#aaa'; context.fillRect(25, 90, 2500, 400); } $(document).ready(function() { draw_a(); }); 
 canvas { border: 1px dotted; } .printOnly { display: none; } @media print { html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; /* height: 100%; width: 100%; position: fixed;*/ top: 0; left: 0; margin: 0; } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } } @media print and (-ms-high-contrast: active), (-ms-high-contrast: none) { html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; /* height: 100%; width: 100%; position: fixed;*/ top: 0; left: 0; margin: 0; padding: 15px; font-size: 14px; line-height: 18px; position: absolute; display: flex; align-items: center; justify-content: center; -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); -o-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button onclick="window.print();" class="no-print">Print Canvas</button> <div class="myDivToPrint"> <div class="Aligner-item"> <canvas height="2500px" width="4000px" id="canvas1"></canvas> <div class="printOnly Aligner-item--bottom"> Print Only</div> </div> </div> 

@media print {  
  @page {
    size: 297mm 210mm; /* landscape */
    /* you can also specify margins here: */
    margin: 25mm;
    margin-right: 45mm; /* for compatibility with both A4 and Letter */
  }
}

 var canvas = document.getElementById("canvas1"); function draw_a() { var context = canvas.getContext("2d"); // // LEVER //plane context.fillStyle = '#aaa'; context.fillRect(25, 90, 2500, 400); } $(document).ready(function() { draw_a(); }); 
 canvas { border: 1px dotted; } .printOnly { display: none; } @media print { @page { size: 297mm 210mm; /* landscape */ /* you can also specify margins here: */ margin: 25mm; margin-right: 45mm; /* for compatibility with both A4 and Letter */ } html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; /* height: 100%; width: 100%; position: fixed;*/ top: 0; left: 0; margin: 0; } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } } @media print and (-ms-high-contrast: active), (-ms-high-contrast: none) { html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; /* height: 100%; width: 100%; position: fixed;*/ top: 0; left: 0; margin: 0; padding: 15px; font-size: 14px; line-height: 18px; position: absolute; display: flex; align-items: center; justify-content: center; -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); -o-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button onclick="window.print();" class="no-print">Print Canvas</button> <div class="myDivToPrint"> <div class="Aligner-item"> <canvas height="2500px" width="4000px" id="canvas1"></canvas> <div class="printOnly Aligner-item--bottom"> Print Only</div> </div> </div> 

浏览器似乎会将大型画布分成多个页面。 我使用最新的chrome和safari浏览器在MacOS Sierra上进行了测试。

打印画布的一种可能方法是首先使用canvas.toDataURL()将其转换为包含图像表示的数据URI 然后,您可以在打印前操纵图像尺寸。

"<img src='" + canvas.toDataURL() + "' height='500px' width='500px' />'"

在下面的示例中,大型4500px x 4500px canvas被转换为img并放置在iframe ,用于打印。 您可以将图像附加到原始文档而不是打印该特定元素,但iframe可能更灵活地处理打印输出。 您可以根据需要操作img尺寸并打印画布的缩放表示。 请注意,我硬编码了图像的widthheight ,但可以根据打印需要进行计算和更改。

由于iframe跨源限制,下面的代码片段在这里不起作用,但它确实适用于此jsfiddle

表示画布的缩放500px500px图像在打印时适合打印在一页上。

 var canvas = document.getElementById("canvas1"); function draw_a() { var context = canvas.getContext("2d"); // // LEVER //plane context.fillStyle = '#aaa'; context.fillRect(25, 90, 4500, 4500); } print = function() { window.frames["myFrame"].focus(); window.frames["myFrame"].print(); } function setupPrintFrame() { $('<iframe id="myFrame" name="myFrame">').appendTo("body").ready(function(){ setTimeout(function(){ $('#myFrame').contents().find('body').append("<img src='" + canvas.toDataURL() + "' height='500px' width='500px' />'"); },50); }); } $(document).ready(function() { draw_a(); setupPrintFrame(); }); 
 canvas { border: 1px dotted; } .printOnly, #myFrame { display: none; } @media print { html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; /* height: 100%; width: 100%; position: fixed;*/ top: 0; left: 0; margin: 0; } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } } @media print and (-ms-high-contrast: active), (-ms-high-contrast: none) { html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; /* height: 100%; width: 100%; position: fixed;*/ top: 0; left: 0; margin: 0; padding: 15px; font-size: 14px; line-height: 18px; position: absolute; display: flex; align-items: center; justify-content: center; -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); -o-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button onclick="print()" class="no-print">Print Canvas</button> <div class="myDivToPrint"> <div class="Aligner-item"> <canvas height="4500px" width="4500px" id="canvas1"></canvas> <div class="printOnly Aligner-item--bottom"> Print Only</div> </div> </div> 

我刚刚使用localhost环境在Firefox和Chrome浏览器中测试了这个小提琴,它在两者中都有用。 这是原始的小提琴

这是我测试的HTML

 var canvas = document.getElementById("canvas1"); function draw_a() { var context = canvas.getContext("2d"); // // LEVER //plane context.fillStyle = '#aaa'; context.fillRect(25, 90, 2500, 400); } $(document).ready(function() { draw_a(); }); 
 div.sizePage { color: #333; } canvas { border: 1px dotted; } .printOnly { display: none; } @media print { html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; /* height: 100%; width: 100%; position: fixed;*/ top: 0; left: 0; margin: 0; } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } } @media print and (-ms-high-contrast: active), (-ms-high-contrast: none) { html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; /* height: 100%; width: 100%; position: fixed;*/ top: 0; left: 0; margin: 0; padding: 15px; font-size: 14px; line-height: 18px; position: absolute; display: flex; align-items: center; justify-content: center; -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); -o-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button onclick="window.print();" class="no-print">Print Canvas</button> <div class="myDivToPrint"> <div class="Aligner-item"> <canvas height="2500px" width="4000px" id="canvas1"></canvas> <div class="printOnly Aligner-item--bottom"> Print Only</div> </div> </div> 

所以我认为可以说现在两种浏览器都支持它。

我在两个浏览器上使用最新的更新。

试试这个!

 var canvas = document.getElementById("canvas1"); function draw_a() { var context = canvas.getContext("2d"); context.fillStyle = '#aaa'; context.fillRect (25, 90, 2500, 400); } $(document).ready(function(){ draw_a(); }); 
 @page Section1 { size:8.27in 11.69in; margin:0; mso-header-margin:0; mso-footer-margin:0; mso-paper-source:0; } 
  <button onclick="window.print();" class="no-print">Print Canvas</button> <div class="myDivToPrint"> <div class="Aligner-item"> <canvas height="2500px" width="4000px" id="canvas1" style="border: solid 10px #000;"></canvas> </div> </div> 

使用纯CSS样式无法处理此问题。 我建议克隆元素多次打印(在这种情况下),将副本放在彼此之后,并使用CSS使它们“仅打印”。 此外,不能只是克隆画布 - 需要为每个副本重绘它。

副本数取决于元素和页面宽度。 默认页面宽度为210mm,可以转换为px( Pixel to Centimeter? )并与元素的宽度进行比较。

当我们有像素的页面宽度时,我们可以分别为每个副本设置负左边距。 有了这个,整个画布将被“划分”成列并从上到下打印。

为了从新页面开始打印每个副本,只需使用此CSS规则:

page-break-before: always;

有很多硬编码的东西,但我认为你可以用它来为你的问题构建一个通用的解决方案。

 var divide = function(selector, pageWidth) { var elementToDivide = document.querySelector(selector); var widthPx = elementToDivide.offsetWidth; var pageWidthPx = pageWidth * 3.7795; for (var i = 1; i <= parseInt(widthPx/pageWidthPx); i++) { var clone = elementToDivide.cloneNode(true); elementToDivide.parentNode.appendChild(clone); draw_a(document.getElementsByTagName("canvas")) clone.style.marginLeft = "-" + (pageWidthPx * i) + "px"; clone.className += " printOnly"; } } var standardPrint = window.print; window.print = function() { if (!window.pagesDivided) { divide(".myDivToPrint", 210); window.pagesDivided = true; } standardPrint(); }; function draw(canvas) { var context = canvas.getContext("2d"); var grd = context.createLinearGradient(0, 0, 4000, 2500); grd.addColorStop(0, "yellow"); grd.addColorStop(1, "red"); context.fillStyle = grd; context.fillRect(25, 25, 4000, 2500); } function draw_a(elem) { if (elem.length != null && elem.length > 1) { for (var i = 0; i < elem.length; i++) { draw(elem[i]); } } else { draw(elem); } } $(document).ready(function() { draw_a(document.getElementById("canvas1")); }); 
 canvas { border: 5px dashed; } .printOnly { display: none; } .myDivToPrint { float: left; } @media print { @page { size: 297mm 210mm; margin: 0mm; margin-right: 0mm; } html, body { height: 100%; background-color: yellow; } .myDivToPrint { page-break-before: always; background-color: yellow; margin: 0; } .no-print, .no-print * { display: none !important; } .printOnly { display: block; page-break-before: always; } } @media print and (-ms-high-contrast: active), (-ms-high-contrast: none) { html, body { height: 100%; background-color: yellow; } .myDivToPrint { background-color: yellow; top: 0; left: 0; margin: 0; padding: 15px; font-size: 14px; line-height: 18px; align-items: center; justify-content: center; } .no-print, .no-print * { display: none !important; } .printOnly { display: block; } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button onclick="window.print();" class="no-print">Print Canvas</button> <div class="myDivToPrint"> <div class="Aligner-item"> <canvas height="2500px" width="4000px" id="canvas1"></canvas> <div class="printOnly Aligner-item--bottom"> Print Only</div> </div> </div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM