打印整个 HTML 页面,包括 iframe 中的 pdf 文件

Posted

技术标签:

【中文标题】打印整个 HTML 页面,包括 iframe 中的 pdf 文件【英文标题】:Print whole HTML page including pdf file inside iframe 【发布时间】:2016-08-01 18:14:33 【问题描述】:

我的任务是在 html 页面中嵌入相对较小的 pdf 文件并打印整个 html pade,包括 iframe 中的 pdf 文件。 这是我的html页面的结构:

这是我的代码:

@media print
	body * display:block;
    .toPrintdisplay:block; border:0; width:100%; min-height:500px
<body>
    <button onclick="window.print()">Print</button>

	<h3>MUST BE PRINTED</h3>
    <p> MUST BE PRINTED</p>
    <iframe class="toPrint" src="https://nett.umich.edu/sites/default/files/docs/pdf_files_scan_create_reducefilesize.pdf" style="width:100%; height:97vh;"></iframe>
	<h3>MUST BE PRINTED</h3>
    <p> MUST BE PRINTED</p>
</body>

目前我正在使用 css @media 查询打印页面。但不幸的是,此媒体查询仅打印 pdf 的 首页

如何打印整个 pdf 文件?

【问题讨论】:

【参考方案1】:

这是一个使用 javascript 的更简单的解决方案。

<body>
        <h3 id='first_h3'>MUST BE PRINTED</h3>
        <p id ='first_paragraph'> MUST BE PRINTED</p>
        <div id="pdfRenderer"></div>
        <h3 id='second_h3'>MUST BE PRINTED</h3>
        <p id='second_paragraph'> MUST BE PRINTED</p>

<input type="submit" value="Print All"
  onclick="javascript:printPage()"
 />

</body>

<script>

 pages =[] // initiate an empty list here

function printPage() 

var first_h3 = document.getElementById('first_h3');
// get the first h3 tag and
// then push its innerHTML into the list
   pages.push(first_h3.innerHTML); 

var first_paragraph = document.getElementById('first_paragraph');
// get the first paragraph and
// then push its innerHTML into the list
   pages.push(first_paragraph.innerHTML); 

var pdfRenderer = document.getElementById('pdfRenderer');
// get the pdfRenderer and
// then push its innerHTML into the list
   pages.push(pdfRenderer.contentWindow.document.body.innerHTML); 

var second_h3 = document.getElementById('second_h3');
// get the second h3 tag and
// then push its innerHTML into the list
   pages.push(second_h3.innerHTML); 

var second_paragraph = document.getElementById('second_paragraph');
// get the second paragraph and
// then push its innerHTML into the list
   pages.push(second_paragraph.innerHTML); 

if (pages && pages.length) 

// this if statement, just checks to ensure our list is not empty before running the code.

// here is the magic, we now set the parent window to be equal to all the concatenated innerHTML
window.content.document.body.innerHTML = pages;
// then we print this new window that contains all the different parts in the exact order we pushed them into the list.
window.print();
 
else 
// do nothing




</script>

使用此解决方案可避免 iframe 超过一页时被切断的问题。其次,即使您有多个 iframe,您也只会得到一个打印对话框。

【讨论】:

【参考方案2】:

我使用 Mozilla 的 pdf.js 来解决我的问题。 它在 html5 画布上呈现 pdf 文件,因此它允许根据需要打印整个 html 页面。

这里是代码(credit):

<html>
<body>

<script type="text/javascript" src="https://raw.github.com/mozilla/pdf.js/gh-pages/build/pdf.js"></script>
<script type="text/javascript">
function renderPDF(url, canvasContainer, options) 
    var options = options ||  scale: 1 ;
        
    function renderPage(page) 
        var viewport = page.getViewport(options.scale);
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        var renderContext = 
          canvasContext: ctx,
          viewport: viewport
        ;
        
        canvas.height = viewport.height;
        canvas.width = viewport.width;
        canvasContainer.appendChild(canvas);
        
        page.render(renderContext);
    
    
    function renderPages(pdfDoc) 
        for(var num = 1; num <= pdfDoc.numPages; num++)
            pdfDoc.getPage(num).then(renderPage);
    
    PDFJS.disableWorker = true;
    PDFJS.getDocument(url).then(renderPages);
   
</script> 
        <h3>MUST BE PRINTED</h3>
        <p> MUST BE PRINTED</p>
		<div id="holder"></div>
        <h3>MUST BE PRINTED</h3>
        <p> MUST BE PRINTED</p>

<script type="text/javascript">
renderPDF('yourFile.pdf', document.getElementById('holder'));
</script>  

</body>
</html>

【讨论】:

【参考方案3】:

使用https://github.com/itext/itextsharpitextsharp 或https://github.com/MrRio/jsPDFjsPDF。通过插件很容易使用

【讨论】:

【参考方案4】:

它没有打印整个 PDF 的原因是它在 iframe 中并且高度是固定的。为了打印整个 PDF,您需要 iframe 高度以匹配其内容高度(iframe 上不应有滚动条)。

另一种选择是仅打印 iframe。将 id 添加到您的 iFrame:

<iframe id="toPrint" class="toPrint"></iframe>

聚焦 iframe 并打印其内容:

var pdfFrame = document.getElementById("toPrint").contentWindow;

pdfFrame.focus();
pdfFrame.print();

【讨论】:

【参考方案5】:

试试这个,它包含一些 JS,但那总是好的。 HTML:

<body>
        <h3>MUST BE PRINTED</h3>
        <p> MUST BE PRINTED</p>
        <div id="pdfRenderer"></div>
        <h3>MUST BE PRINTED</h3>
        <p> MUST BE PRINTED</p>
    </body>

JS:

var pdf = new PDFObject(
  url: "https://nett.umich.edu/sites/default/files/docs/pdf_files_scan_create_reducefilesize.pdf",
  id: "pdfRendered",
  pdfOpenParams: 
    view: "FitH"
  
).embed("pdfRenderer");

这应该可行。如果我没有,现在让我来

【讨论】:

嗨,@Rik。我已经尝试过你的建议。此外,我使用pdfobject.com 文档使事情更清楚,但问题仍然存在,我无法打印整个页面,包括#pdfRenderer div 中的 pdf 文件。 为什么要在为 PDF 制作的 div 中打印 HTML? 嗨,@Rik。我有一个带有标准页眉和页脚的文档。在这两者之间,我需要注入自定义 pdf 许可协议。因此我需要能够打印标准文档。页眉和页脚之间带有自定义 pdf。我的客户必须打印协议才能签署。

以上是关于打印整个 HTML 页面,包括 iframe 中的 pdf 文件的主要内容,如果未能解决你的问题,请参考以下文章

zai页面中嵌套了一个iframe 框,怎么能够让iframe 中的提示框在整个页面查看,而不是只是在那个框中

window.print()打印页面指定内容(使用iframe保证原页面不失效)

无法从 IE 11 中的父页面打印 iframe 内容

如何确定iframe中的页面在该iframe中的默认位置

网页中如何实现点击iframe中的一个链接,使整个页面(不是只有iframe)跳转到新的页面

post方式加载iframe