iT邦幫忙

0

如何使用window.print()在印完指定的高度後換下一頁

  • 分享至 

  • xImage

請問各位,
紙張格式為A4直印,在列印特定區塊時希望可以在指定高度換頁(例:經過144mm後換下一頁)。
目前在使用window.print(),查詢chatGPT及做一些測試,但沒有達到希望的要求,
想請教如何調整或撰寫呢? 謝謝
補充:
1.瀏覽器為chrome。先假設定pdf列印,印出的效果沒有換頁。
2.放錯版面,重新發文,不好意思

列印畫面
範例CODE如下:

<!DOCTYPE html>
<style>
    @media print {
        @page {
            size: A4 portrait;
        }

        #printDiv {
            font-size: 50px;
            height: 100mm;
            page-break-after: always;

        }
    }
</style>

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>Print specific block with orientation selection</h1>
    <div id="printDiv">
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
            <li>10</li>
            <li>11</li>
            <li>12</li>
            <li>13</li>
            <li>14</li>
            <li>15</li>
            <li>16</li>
            <li>17</li>
            <li>18</li>
            <li>19</li>
            <li>20</li>
            <li>21</li>
            <li>22</li>
            <li>23</li>
            <li>24</li>
            <li>25</li>
        </ul>
    </div>
    <div>
        <button onclick="printBlock()">Print</button>
    </div>
    <script>
        function printBlock() {
            window.print();
        }
    </script>
</body>


</html>

今天測試如下,我的資料有分head與body。因為這個範例用li,改用成算li的方式,head、li、footer分別佔多少,計算過多少就把頁面break。但我的實際資料是用table,可能還要實驗或請教各位是否有其他更簡易方法?例:頁面過100mm就換頁?

<!DOCTYPE html>
<style>
    @media print {
        @page {
            size: A4 portrait;
        }

        #printDiv {
            font-size: 50px;
            /* height: 50%; */
            overflow: visible;
            /* page-break-after: always; */
        }

        #printDiv li.page-break {
            page-break-after: always;
        }

    }
</style>

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>Print specific block with orientation selection</h1>
    <div id="printDiv">
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
            <li>10</li>
            <li>11</li>
            <li>12</li>
            <li>13</li>
            <li>14</li>
            <li>15</li>
            <li>16</li>
            <li>17</li>
            <li>18</li>
            <li>19</li>
            <li>20</li>
            <li>21</li>
            <li>22</li>
            <li>23</li>
            <li>24</li>
            <li>25</li>
        </ul>
    </div>
    <div>
        <button onclick="printBlock()">Print</button>
    </div>
    <script>
        function printBlock() {
            const lis = document.querySelectorAll('#printDiv li');
            let count = 0;
            for (let i = 0; i < lis.length; i++) {
                count++;
                if (i === 4) {
                    lis[i].classList.add('page-break');
                    count = 0;
                }
                if (i !== 4 && count >= 6) {
                    lis[i].classList.add('page-break');
                    count = 0;
                }
            }
            window.print();
        }
    </script>
</body>


</html>
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
kw6732
iT邦研究生 4 級 ‧ 2023-05-08 14:42:32

這樣改

.printDiv {
            font-size: 50px;
            height: 100mm;
            page-break-after: always;

        }

看要抓幾個li可以符合實際高度

<div id="printpage1" class="printDiv">
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
            <li>10</li>
            <li>11</li>
            <li>12</li>
        </ul>
</div>
<div id="printpage1" class="printDiv">
        <ul>
            <li>13</li>
            <li>14</li>
            <li>15</li>
            <li>16</li>
            <li>17</li>
            <li>18</li>
            <li>19</li>
            <li>20</li>
            <li>21</li>
            <li>22</li>
            <li>23</li>
            <li>24</li>
            <li>25</li>
        </ul>
</div>
0
re.Zero
iT邦研究生 5 級 ‧ 2023-05-10 00:00:27

給個範例, 說明在程式碼內~

  • 第 1 個 ul (color:blue) 是基本對照用, 沒用上特殊控制手段。
  • 第 2 個 ul (color:green) 是採用 「 JavaScript + 上方的表格控制項 」 來控制的; 可修改 "Block Height" 來控制限制大小。
  • 第 3 個 ul (color:red) 是採用 CSS (:nth-child(12n+1)) 來控制的; 只能控制每頁最多數量。

( 其實 CSS 還有 named-page (@page) 控制方式, 但多數瀏覽器支援程度很差; 此時的我在 Chrome 與 Firefox 都實作不出來~ )

<!DOCTYPE html>
<html lang="zh-Hant-TW" xmlns="http://www.w3.org/1999/xhtml">
	<head><meta charset="UTF-8" /><title>myBlank - Dark</title>
		<style>
@media all {
	/*- 這 區塊(@media all): 只是觀察用的計數器; -*/
	@counter-style decimal-leading-zero {
		system 	: extends decimal;
		pad 	: 4 '0';
	}
	ul >li:nth-of-type(1) {counter-reset:mySerial;}
	ul >li {counter-increment:mySerial;}
	ul >li::before {
		content 	: "#" counter(mySerial, decimal-leading-zero) ": ";
		opacity 	: 0.5;
	}
}
@media all {
	/*- 這區塊: 字型、 排版、 填充、 高顯; -*/
	*|*:root {
		font-size 		: 1.0em;
		line-height 	: 1.5em;
	}
	form#printCtl {
		padding 	: 0.25em 0.5ex;
		border 		: 1px solid hsla( 0, 0%, 50%, 0.5 );
		border-radius 	: 5px;
		margin 		: auto;
	}
	form#printCtl >input[type="text"] {max-width:4.25em}
	ul >li {
		font-size 		: 1.5em;
		line-height 	: 1.75em;
	}
	ul >li::after {
		content 	: " "
			"1234567890"
			"1234567890"
			"1234567890";
		opacity 	: 0.25;
	}
	body >ul:nth-of-type(1) {color:blue}
	body >ul:nth-of-type(2) {color:green}
	body >ul:nth-of-type(3) {color:red}
}
@media print {
	/*- 這 區塊(@media print) 做列印內容樣式控制; -*/
	@page {
		/*- 列印頁面基本設定; -*/
		size 	: A4 portrait;
		margin 	: 15mm;
	}
	/*- hideInPrint: 列印時隱藏物件用(例如 form#printCtl); -*/
	.hideInPrint, .hideInPrint * {display:none}
	/*- pageBreakBefore: 就只是個 page-break; -*/
	.pageBreakBefore {page-break-before:always}
	/*- breakBy12Li: 每 12 個 li 就分頁; -*/
	.breakBy12Li >li:nth-child(12n+1) {page-break-before:always}
}
		</style>
		<script type="text/javascript">
window.addEventListener("beforeprint", (event) => {
	/*- 在列印事件前執行此段內容; -*/
	const myUL01Objs = document.querySelectorAll('ul#breakWithJS');
	const myPixelDensity = document.querySelector('input#myPixelDensity').value;
	const myBlockHeight = document.querySelector('input#myBlockHeight').value;
	if(myUL01Objs.length){
		if(myUL01Objs[0].children.length){
			const myLIs = myUL01Objs[0].children;
			let accumHeight = 0;
			for(let i = 0; i < myLIs.length; i++) {
				/*- 這裡的演算與流程我隨便寫的給你當參考範例, 
				可能會有問題, 請自行視需求與現況修改~ 
				( 例如 myBlockHeight > pageHeight 時~ ) -*/
				accumHeight += myLIs[i].offsetHeight;
				if((accumHeight *25.4 /myPixelDensity) > myBlockHeight){
					myLIs[i].classList.add('pageBreakBefore');
					accumHeight = myLIs[i].offsetHeight;
				}
			};
		};
	};
});
window.addEventListener("afterprint", (event) => {
	/*- 印完後清除 li 的 pageBreakBefore; 
	( 注意, 這裡沒有檢查 li 原本是否有 pageBreakBefore 而是一律清除喔! ) -*/
	const myUL01Objs = document.querySelectorAll('ul#breakWithJS');
	if(myUL01Objs.length){
		if(myUL01Objs[0].children.length){
			const myLIs = myUL01Objs[0].children;
			for(let i = 0; i < myLIs.length; i++) {
				myLIs[i].classList.remove('pageBreakBefore');
			};
		};
	};
});
		</script>
	</head>
	<body>
		<form id="printCtl" class="hideInPrint" onsubmit="event.preventDefault();return false;">
			<label for="myPixelDensity"><a href="https://www.w3.org/TR/css3-values/#absolute-lengths">Pixel Density</a></label>:
			<input type="text" id="myPixelDensity" name="myPixelDensity" value="96">(pixels/in)<br/>
			<label for="myBlockHeight">Block Height</label>:
			<input type="text" id="myBlockHeight" name="myBlockHeight" value="200">(mm)<br/>
			&nbsp;<button onclick="window.print();">Print</button>
		</form>
		</p>
		<h1>just printing</h1>
		<p>第 1 個 ul (color:blue) 是基本對照用, 沒用上特殊控制手段。</p>
		<p>第 2 個 ul (color:green) 是採用 「 JavaScript + 上方的表格控制項 」 來控制的; 可修改 "Block Height" 來控制限制大小。</p>
		<p>第 3 個 ul (color:red) 是採用 CSS (":nth-child(12n+1)") 來控制的; 只能控制每頁最多數量。</p>
		<p>( 其實 CSS 還有 named-page (@page) 控制方式, 但多數瀏覽器支援程度很差; 此時的我在 Chrome 與 Firefox 都實作不出來~ )</p>
		<ul title="基本對照用" class="pageBreakBefore">
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
		</ul></div>
		<ul title="Breaking with JS" class="pageBreakBefore" id="breakWithJS">
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
		</ul></div>
		<ul title="每 12 個 li 分為一頁" class="breakBy12Li pageBreakBefore">
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>0</li>
		</ul></div>
	</body>
</html>

我要發表回答

立即登入回答