Css iframed页面的打印父窗口会导致奇数缩放

Css iframed页面的打印父窗口会导致奇数缩放,css,iframe,printing,zooming,Css,Iframe,Printing,Zooming,我的任务是将几个HTML文档合并成一个页面进行打印。我的第一次尝试失败得很惨——我试图将每个页面内容隔离在各自的标记中,并修改样式表规则以匹配它们。我的第二次尝试是使用iframe来隔离每个文档,它看起来明显更好,但是当从iframe堆栈的父框架打印时,页面会放大,而不是在各自的窗口中单独打印文档 下面是我正在使用的文档的一个示例: 你可以在Firefox中进行打印预览,看看我的意思。如果在其自己的选项卡/窗口中打开第一个框架并打印预览,则轮廓框将非常适合页面。在iframe堆栈的父窗口中执行相

我的任务是将几个HTML文档合并成一个页面进行打印。我的第一次尝试失败得很惨——我试图将每个页面内容隔离在各自的
标记中,并修改样式表规则以匹配它们。我的第二次尝试是使用iframe来隔离每个文档,它看起来明显更好,但是当从iframe堆栈的父框架打印时,页面会放大,而不是在各自的窗口中单独打印文档

下面是我正在使用的文档的一个示例:

你可以在Firefox中进行打印预览,看看我的意思。如果在其自己的选项卡/窗口中打开第一个框架并打印预览,则轮廓框将非常适合页面。在iframe堆栈的父窗口中执行相同操作,将显示页面边界外的单元格


免责声明:我没有对这些页面进行编码。是的,我知道它们很可怕。不幸的是,该项目没有时间或预算以这样的方式重做页面,以实现打印一组文档的单个页面的目标。我可能会暂时要求用户单独打印每个页面以进行适当的缩放,但我仍然希望了解可能导致此问题的原因。

问题是浏览器使用容器iframe的宽度来确定如何缩放该框架的内容以进行打印。因此,需要明确确定帧的宽度

不幸的是,动态计算打印宽度是相当棘手的,涉及一些黑客。您最好只设置一个固定宽度的组件页面样式,并将iframe宽度硬编码为该宽度

但是,如果确实需要动态调整它们的大小,则可以在加载文档(在Chrome中测试)后运行以下代码:

相反,这可能会解决大多数情况,但我没有对较旧的浏览器做出承诺

祝你好运,很抱歉听到你被那些页面上的代码卡住了




编辑:上述解决方案在Firefox中有点不可靠

Firefox解决方案(在Firefox 5中测试和使用):

var iframes = document.getElementsByTagName("iframe");
for(var i = 0; i < iframes.length; ++i) {
    var curFrame = iframes[i];
    var curBody = curFrame.contentDocument.body;
    var oldHTML = curBody.innerHTML;
    curBody.innerHTML = '<div id="iframe-print-content" style="display:inline-block; overflow:hidden;">' +  oldHTML + '</div>';
    var printContent = curFrame.contentDocument.getElementById("iframe-print-content");
    var curWidth = printContent.offsetWidth + printContent.offsetLeft + 25;
    var curHeight = printContent.offsetHeight + printContent.offsetTop + 25;
    curBody.innerHTML = oldHTML;
    iframes[i].style.width=(curWidth + "px");
    iframes[i].style.height=(curHeight + "px");
}
var-iframes=document.getElementsByTagName(“iframe”);
对于(变量i=0;i
有关此通用方法工作原理的完整解释,请参见上面的答案

与上述解决方案有什么不同,为什么?

首先,Firefox的细节:
有几个关键的区别。首先要注意的是Firefox处理
display:inline block
white space:nowrap
的方式与Chromium/WebKit处理固定宽度元素的方式不同(这就是为什么有一个文档看起来与前面的代码不一致的原因)。接下来要注意的是,Firefox喜欢在iFrame中留出一点空白。我对Firefox的代码不是很熟悉(我每天都在Chromium上进行黑客攻击),但我通常的解决方案(除了避免使用框架)是在页边留出额外的25px。像这样的一小笔钱似乎是解决这类问题的常用方法

现在,代码中实际上更好的部分:
首先,它现在存储旧身体,将身体提升到div上进行测量,然后恢复旧身体。这将避免僵化CSS的问题,并应保证更可预测的行为。第二,这对高度和宽度做了同样的事情(我之前的假设是硬编码的宽度会起作用,这是一个更灵活的解决方案)

为什么这仍然很糟糕?

去掉
空白:nowrap
将在Chromium/WebKit上打印时进行文本换行。它仍然可以很好地打印,但并不完全正确,因为会有一些额外的文本被包装。要使这成为一个真正可行的解决方案,您仍然需要执行浏览器检测代码

同样,我建议使用此代码快速计算出适当的宽度和高度,然后测试并硬编码每个浏览器的正确大小。这是一个丑陋的解决方案,但它最终是这种情况下唯一真正可靠的解决方案。

< P>我相信你可以(再)“欺骗”浏览器,在中间添加一个静态宽度。这将强制打印版本调整大小,将所有信息重新显示在页面上。。。我只修改了这个iFrame,并重新调整了大小(注意宽度:150%):



500!看起来不错!你能把这些文件放在zip里,然后把链接贴在这里吗?一定会试试的!这是一个文件压缩包:抱歉,无法修复它。我建议最好的方法是尝试通过ajax加载内容,而不是使用iFrame。如上所述,我已经尝试过将表单的内容隔离在自己的包含
div
s的文档中,从而将表单合并到一个文档中,但失败得很惨——样式表和糟糕的标记没有很好地结合在一起。除了完全以PDF模板或其他方式重做它们之外,iFrame看起来是我最好的选择。谢谢你的回答。如果您注意到,每个iframed页面的样式表已经在其容器中明确定义了宽度。有些有
6.9in
,有些有
940px
,有些有
7.55in
。我会给iFrame一个明确的宽度,但是对容器有什么想法吗?你要小心一点;容器的宽度不一致
display:-moz-inline-stack; display:inline-block; zoom:1; *display:inline; overflow:hidden; white-space: nowrap;
var iframes = document.getElementsByTagName("iframe");
for(var i = 0; i < iframes.length; ++i) {
    var curFrame = iframes[i];
    var curBody = curFrame.contentDocument.body;
    var oldHTML = curBody.innerHTML;
    curBody.innerHTML = '<div id="iframe-print-content" style="display:inline-block; overflow:hidden;">' +  oldHTML + '</div>';
    var printContent = curFrame.contentDocument.getElementById("iframe-print-content");
    var curWidth = printContent.offsetWidth + printContent.offsetLeft + 25;
    var curHeight = printContent.offsetHeight + printContent.offsetTop + 25;
    curBody.innerHTML = oldHTML;
    iframes[i].style.width=(curWidth + "px");
    iframes[i].style.height=(curHeight + "px");
}
<iframe src="order/form.html" style="height: 1707px;width:150%">