如何使iframe打印的收据发票高度达到收据发票内容的最大高度?
How to make height of receipt invoice print from iframe to the maximum height of content in the receipt invoice?
我正在尝试使用 iframe
从浏览器打印收据发票。我能够调用打印,并且能够在浏览器打印 window 中显示收据。但是收据的高度超过了收据的最大内容,造成了纸张的浪费。
这是我到目前为止所做的。
HTML
:
<!DOCTYPE html>
<html lang="en">
<body>
<button id="print">Print</button>
<section id="section-to-print">
<header>
<h1>Brand Name</h1>
<hr />
<address>Address: #1234,<br /> Street,<br /> Area,<br />
District - PinCode</address>
<p>Phone: 22334455</p>
<p>Mobile: 9876543210</p>
<p>GSTIN: GSTIN123456789</p>
</header>
<hr />
<main>
<section id="customerdetails">
<h3>Abdul Rahman</h3>
</section>
<hr />
<section id="invoicedetails">
<p>Invoice No: 1234</p>
<p>Invoice Date: 24 MAR 2022)</p>
<p>Payment Mode: Cash</p>
<p>Total Amount: 1234</p>
<p>Serviced By: Undertaker</p>
</section>
<hr />
<section id="invoiceitems">
<div class="header justify-self-start">Description</div>
<div class="header">Qty</div>
<div class="header justify-self-end">Price</div>
<div class="item justify-self-start">Category <br /> - Item</div>
<div class="unit">1</div>
<div class="price justify-self-end">100</div>
<div class="footer justify-self-start font-bold">Total QTY</div>
<div class="footer justify-self-start font-bold">1</div>
<div></div>
<div class="footer justify-self-start span-2 font-bold">Sub Total</div>
<div class="footer justify-self-end font-bold">90</div>
<div class="footer justify-self-start span-2 font-bold">DISCOUNT</div>
<div class="footer justify-self-end align-self-center font-bold">-10</div>
<div class="footer justify-self-start span-2 font-bold">CGST (1%)</div>
<div class="footer justify-self-end align-self-center font-bold">1</div>
<div class="footer justify-self-start span-2 font-bold">SGST (1%)</div>
<div class="footer justify-self-end align-self-center font-bold">1</div>
<div class="footer justify-self-start span-2 font-bold">ROUNDOFF</div>
<div class="footer justify-self-end align-self-center font-bold">-0.01</div>
<div class="footer justify-self-start span-2 font-bold">TOTAL</div>
<div class="footer justify-self-end align-self-center font-bold">100</div>
</section>
<hr />
<section id="invoicesummary">
<p>Total Amount in Words ($)</p>
<p>ONE HUNDRED ONLY</p>
</section>
</main>
<hr />
<footer>
<p><small>Thank you for the business</small></p>
<p><small>This is a computer generated invoice</small></p>
</footer>
</section>
<script>
window.addEventListener("DOMContentLoaded", function () {
document.getElementById("print").addEventListener("click", function () {
var iframe = document.querySelector('#invoice-print') || document.createElement('iframe');
iframe.setAttribute("id", "invoice-print");
document.body.appendChild(iframe);
iframe.contentWindow.document.body.innerHTML = document.querySelector('#section-to-print').innerHTML;
var printScript = document.createElement("script");
printScript.innerHTML = `function setPrintStyles(pagesize) {
var documentHeight = document.getElementsByTagName('html')[0].offsetHeight;
var css = \`@media print { @page { size: $\{pagesize} $\{documentHeight}px; } }\`,
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.appendChild(style);
style.type = 'text/css';
style.appendChild(document.createTextNode(css));
}`;
iframe.contentWindow.document.head.appendChild(printScript);
var bodyScript = document.createElement("script");
bodyScript.innerHTML = `fetch('${window.location.origin}/receipt.css')
.then(response => response.text())
.then(data => {
var head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.appendChild(style);
style.type = 'text/css';
style.appendChild(document.createTextNode(data));
setPrintStyles('2.7in');
window.print();
});`;
iframe.contentWindow.document.body.appendChild(bodyScript);
});
});
</script>
</body>
</html>
Receipt CSS:
@media print {
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
html, body {
margin: 0 2px;
height: max-content;
}
body {
font-family: Calibri;
text-align: center;
font-size: 0.8rem;
}
p, h1, h3 {
margin: 0.25rem 0;
}
#customerdetails {
text-transform: uppercase;
}
main #invoiceitems {
display: grid;
grid-template-columns: auto min-content max-content;
grid-column-gap: 1px;
}
main #invoiceitems .header {
text-transform: uppercase;
font-weight: bold;
}
main #invoiceitems .item {
text-align: left;
}
main #invoiceitems .price {
text-align: right;
}
main .justify-self-start {
justify-self: start;
}
main .justify-self-end {
justify-self: end;
}
main .align-self-center {
align-self: center;
}
main .span-2 {
grid-column-start: 1;
grid-column-end: 3;
}
footer {
margin-top: 0.75rem;
text-transform: uppercase;
}
#invoicesummary {
text-transform: uppercase;
font-weight: bold;
}
.font-bold {
font-weight: bold;
}
}
实际输出 - 额外高度导致纸张浪费:
预期输出 - 要获得内容的准确高度:
当我点击打印按钮时,我想让收据的高度达到最大内容。我尝试使用以下代码 var documentHeight = document.getElementsByTagName('html')[0].offsetHeight;
在 iframe 中设置页面高度。但高度仍然几乎是内容高度的两倍。请协助我做错了什么。
最后,我通过将 documentHeight
减少到 half
并在我的 iframe
脚本 [=17] 中添加 50px
的呼吸 space 来解决这个问题=]
TLDR:
来自
var documentHeight = document.getElementsByTagName('html')[0].offsetHeight;
到
var documentHeight = `${(iframe.contentWindow.document.body.offsetHeight / 2) + 50}`;
这给出了如下所示的预期输出。
我正在尝试使用 iframe
从浏览器打印收据发票。我能够调用打印,并且能够在浏览器打印 window 中显示收据。但是收据的高度超过了收据的最大内容,造成了纸张的浪费。
这是我到目前为止所做的。
HTML
:
<!DOCTYPE html>
<html lang="en">
<body>
<button id="print">Print</button>
<section id="section-to-print">
<header>
<h1>Brand Name</h1>
<hr />
<address>Address: #1234,<br /> Street,<br /> Area,<br />
District - PinCode</address>
<p>Phone: 22334455</p>
<p>Mobile: 9876543210</p>
<p>GSTIN: GSTIN123456789</p>
</header>
<hr />
<main>
<section id="customerdetails">
<h3>Abdul Rahman</h3>
</section>
<hr />
<section id="invoicedetails">
<p>Invoice No: 1234</p>
<p>Invoice Date: 24 MAR 2022)</p>
<p>Payment Mode: Cash</p>
<p>Total Amount: 1234</p>
<p>Serviced By: Undertaker</p>
</section>
<hr />
<section id="invoiceitems">
<div class="header justify-self-start">Description</div>
<div class="header">Qty</div>
<div class="header justify-self-end">Price</div>
<div class="item justify-self-start">Category <br /> - Item</div>
<div class="unit">1</div>
<div class="price justify-self-end">100</div>
<div class="footer justify-self-start font-bold">Total QTY</div>
<div class="footer justify-self-start font-bold">1</div>
<div></div>
<div class="footer justify-self-start span-2 font-bold">Sub Total</div>
<div class="footer justify-self-end font-bold">90</div>
<div class="footer justify-self-start span-2 font-bold">DISCOUNT</div>
<div class="footer justify-self-end align-self-center font-bold">-10</div>
<div class="footer justify-self-start span-2 font-bold">CGST (1%)</div>
<div class="footer justify-self-end align-self-center font-bold">1</div>
<div class="footer justify-self-start span-2 font-bold">SGST (1%)</div>
<div class="footer justify-self-end align-self-center font-bold">1</div>
<div class="footer justify-self-start span-2 font-bold">ROUNDOFF</div>
<div class="footer justify-self-end align-self-center font-bold">-0.01</div>
<div class="footer justify-self-start span-2 font-bold">TOTAL</div>
<div class="footer justify-self-end align-self-center font-bold">100</div>
</section>
<hr />
<section id="invoicesummary">
<p>Total Amount in Words ($)</p>
<p>ONE HUNDRED ONLY</p>
</section>
</main>
<hr />
<footer>
<p><small>Thank you for the business</small></p>
<p><small>This is a computer generated invoice</small></p>
</footer>
</section>
<script>
window.addEventListener("DOMContentLoaded", function () {
document.getElementById("print").addEventListener("click", function () {
var iframe = document.querySelector('#invoice-print') || document.createElement('iframe');
iframe.setAttribute("id", "invoice-print");
document.body.appendChild(iframe);
iframe.contentWindow.document.body.innerHTML = document.querySelector('#section-to-print').innerHTML;
var printScript = document.createElement("script");
printScript.innerHTML = `function setPrintStyles(pagesize) {
var documentHeight = document.getElementsByTagName('html')[0].offsetHeight;
var css = \`@media print { @page { size: $\{pagesize} $\{documentHeight}px; } }\`,
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.appendChild(style);
style.type = 'text/css';
style.appendChild(document.createTextNode(css));
}`;
iframe.contentWindow.document.head.appendChild(printScript);
var bodyScript = document.createElement("script");
bodyScript.innerHTML = `fetch('${window.location.origin}/receipt.css')
.then(response => response.text())
.then(data => {
var head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.appendChild(style);
style.type = 'text/css';
style.appendChild(document.createTextNode(data));
setPrintStyles('2.7in');
window.print();
});`;
iframe.contentWindow.document.body.appendChild(bodyScript);
});
});
</script>
</body>
</html>
Receipt CSS:
@media print {
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
html, body {
margin: 0 2px;
height: max-content;
}
body {
font-family: Calibri;
text-align: center;
font-size: 0.8rem;
}
p, h1, h3 {
margin: 0.25rem 0;
}
#customerdetails {
text-transform: uppercase;
}
main #invoiceitems {
display: grid;
grid-template-columns: auto min-content max-content;
grid-column-gap: 1px;
}
main #invoiceitems .header {
text-transform: uppercase;
font-weight: bold;
}
main #invoiceitems .item {
text-align: left;
}
main #invoiceitems .price {
text-align: right;
}
main .justify-self-start {
justify-self: start;
}
main .justify-self-end {
justify-self: end;
}
main .align-self-center {
align-self: center;
}
main .span-2 {
grid-column-start: 1;
grid-column-end: 3;
}
footer {
margin-top: 0.75rem;
text-transform: uppercase;
}
#invoicesummary {
text-transform: uppercase;
font-weight: bold;
}
.font-bold {
font-weight: bold;
}
}
实际输出 - 额外高度导致纸张浪费:
预期输出 - 要获得内容的准确高度:
当我点击打印按钮时,我想让收据的高度达到最大内容。我尝试使用以下代码 var documentHeight = document.getElementsByTagName('html')[0].offsetHeight;
在 iframe 中设置页面高度。但高度仍然几乎是内容高度的两倍。请协助我做错了什么。
最后,我通过将 documentHeight
减少到 half
并在我的 iframe
脚本 [=17] 中添加 50px
的呼吸 space 来解决这个问题=]
TLDR:
来自
var documentHeight = document.getElementsByTagName('html')[0].offsetHeight;
到
var documentHeight = `${(iframe.contentWindow.document.body.offsetHeight / 2) + 50}`;
这给出了如下所示的预期输出。