亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

搜索

利用JavaScript和Data URI實現(xiàn)網(wǎng)頁特定元素打印教程

DDD
發(fā)布: 2025-10-16 12:21:12
原創(chuàng)
512人瀏覽過

利用JavaScript和Data URI實現(xiàn)網(wǎng)頁特定元素打印教程

本教程詳細介紹了如何使用javascript將網(wǎng)頁中的特定html元素(如收據(jù))打印到pdf或紙張。通過將目標元素的html內(nèi)容封裝為data uri并在新窗口中打開,結合內(nèi)聯(lián)javascript觸發(fā)自動打印,實現(xiàn)了一種高效且用戶友好的局部內(nèi)容打印解決方案,避免了復雜的內(nèi)容隱藏與恢復操作。

在構建復雜的網(wǎng)頁應用時,經(jīng)常會遇到需要打印頁面特定區(qū)域內(nèi)容的需求,例如電商網(wǎng)站的訂單收據(jù)、報告或證書。傳統(tǒng)的做法可能涉及通過JavaScript動態(tài)隱藏或顯示頁面元素,但這通常會導致頁面閃爍或復雜的DOM操作。本教程將介紹一種更為優(yōu)雅且自動化的方法,利用Data URI和內(nèi)聯(lián)JavaScript實現(xiàn)特定元素的打印功能。

核心原理概述

本方案的核心在于以下幾個關鍵技術點:

  1. Data URI (數(shù)據(jù)統(tǒng)一資源標識符):Data URI 允許我們將小型文件直接嵌入到HTML、CSS或JavaScript中,而無需外部鏈接。在這里,我們將待打印的HTML內(nèi)容編碼成一個Data URI,瀏覽器可以將其作為一個獨立的HTML頁面進行渲染。
  2. window.print() 方法:這是瀏覽器內(nèi)置的打印功能,調(diào)用它會彈出操作系統(tǒng)的打印對話框,允許用戶選擇打印機或保存為PDF。
  3. 內(nèi)聯(lián) JavaScript:為了實現(xiàn)自動打印,我們將在Data URI所承載的HTML內(nèi)容中嵌入一段JavaScript代碼,使其在新頁面加載完成后自動調(diào)用 window.print()。
  4. 動態(tài)樣式注入:為了確保打印內(nèi)容的最佳呈現(xiàn),我們可以在打印前動態(tài)注入額外的CSS樣式,例如居中布局。

HTML 結構準備

首先,需要將你希望打印的特定內(nèi)容(例如收據(jù)表格)封裝在一個獨立的容器元素中。這樣做有助于JavaScript精確地獲取其HTML內(nèi)容。同時,為了打印時的樣式一致性,建議將與該內(nèi)容相關的CSS樣式直接嵌入到該容器內(nèi)部或其子元素中,以確保在新打開的打印頁面中樣式能夠正確應用。

以下是一個收據(jù)表格的HTML結構示例,它被包裹在一個 section 標簽內(nèi),并且其樣式直接嵌入在表格中:

立即學習Java免費學習筆記(深入)”;

<section class="receipt-section">
    <table class="receipt">
      <style>
        /* 收據(jù)表格的專用樣式 */
        .receipt {
          border-collapse: collapse;
          max-width: 80%;
          font-family: sans-serif;
          /* 初始樣式,打印時可能需要調(diào)整 */
        }

        .receipt td {
          padding: .5em;
        }

        .receipt tr:nth-child(even) {
          border: 1px solid #333;
          border-inline: none;
          background: #ddd;
        }

        .receipt tr:nth-child(odd) {
          background: #fff
        }

        .header-Uprice,
        .item-Uprice,
        .header-qty,
        .item-qty {
          text-align: center
        }

        .total {
          border-bottom: 3px double #000
        }
      </style>
      <tr class="table-headers">
        <td class="header-id">#</td>
        <td class="header-desc">Item Description</td>
        <td class="header-Uprice">Unit Price</td>
        <td class="header-qty">Qty</td>
        <td class="header-price">Price</td>
      </tr>
      <tr class="item" id="1">
        <td class="item-id">1</td>
        <td class="item-desc">Dummy Item1</td>
        <td class="item-Uprice">200$</td>
        <td class="item-qty">1</td>
        <td class="item-price">200$</td>
      </tr>
      <tr class="item" id="2">
        <td class="item-id">2</td>
        <td class="item-desc">Dummy Item2</td>
        <td class="item-Uprice">75$</td>
        <td class="item-qty">1</td>
        <td class="item-price">75$</td>
      </tr>
      <tr class="item" id="3">
        <td class="item-id">3</td>
        <td class="item-desc">Dummy Item3</td>
        <td class="item-Uprice">100$</td>
        <td class="item-qty">2</td>
        <td class="item-price">200$</td>
      </tr>
      <tr class="total">
        <td>Total</td>
        <td></td>
        <td></td>
        <td></td>
        <td>475$</td>
      </tr>
    </table>
</section>
登錄后復制

JavaScript 實現(xiàn)步驟

接下來是實現(xiàn)打印功能的JavaScript代碼。我們將創(chuàng)建一個函數(shù),該函數(shù)在被調(diào)用時執(zhí)行以下操作:

  1. 獲取目標內(nèi)容并注入打印邏輯 首先,獲取包含收據(jù)的 table 元素。然后,向其內(nèi)部動態(tài)注入一個 <script> 標簽。這個腳本會在新頁面加載完成后執(zhí)行,首先應用一些額外的打印樣式(例如居中),然后調(diào)用 window.print() 觸發(fā)打印。

    function printReceipt() {
      const receiptTable = document.querySelector('.receipt');
      // 動態(tài)注入用于打印居中的CSS樣式,這里通過修改已有的style標簽實現(xiàn)
      // 注意:這里假設receiptTable內(nèi)部有一個<style>標簽,或者可以直接在receiptTable上添加style屬性
      const cssCenteringScript = `
        const styleTag = document.querySelector('table.receipt > style');
        if (styleTag) {
          styleTag.innerHTML += '.receipt { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0; }';
        } else {
          // 如果沒有內(nèi)聯(lián)style標簽,則創(chuàng)建一個并注入
          const newStyle = document.createElement('style');
          newStyle.innerHTML = '.receipt { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0; }';
          document.head.appendChild(newStyle);
        }
      `;
    
      // 注入自動打印的腳本到收據(jù)表格內(nèi)容中
      // 注意:這里將腳本直接添加到receiptTable的innerHTML,確保它在新頁面中被執(zhí)行
      receiptTable.innerHTML += `<script>window.onload = () => { ${cssCenteringScript}; window.print(); }</script>`;
    
      // ... 后續(xù)步驟
    }
    登錄后復制
  2. 構建 Data URI 在注入腳本后,獲取包含整個 section 的完整HTML內(nèi)容。然后,使用 encodeURIComponent 對這段HTML字符串進行編碼,并前綴 data:text/html, 來構建Data URI。

    function printReceipt() {
      // ... (前面注入腳本的代碼) ...
    
      const receiptSectionHTML = document.querySelector('.receipt-section').innerHTML;
      const dataUri = 'data:text/html,' + encodeURIComponent(receiptSectionHTML);
    
      // ... 后續(xù)步驟
    }
    登錄后復制
  3. 在新窗口中打開并觸發(fā)打印 最后,使用 window.open() 方法在新標簽頁或新窗口中打開這個Data URI。由于Data URI中包含了自動打印的腳本,新頁面加載后將立即彈出打印對話框。

    function printReceipt() {
      const receiptTable = document.querySelector('.receipt');
      const cssCenteringScript = `
        const styleTag = document.querySelector('table.receipt > style');
        if (styleTag) {
          styleTag.innerHTML += '.receipt { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0; }';
        } else {
          const newStyle = document.createElement('style');
          newStyle.innerHTML = '.receipt { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0; }';
          document.head.appendChild(newStyle);
        }
      `;
    
      // 保存原始HTML,以便在注入后可以恢復
      const originalReceiptTableHTML = receiptTable.innerHTML;
    
      receiptTable.innerHTML += `<script>window.onload = () => { ${cssCenteringScript}; window.print(); }</script>`;
    
      const receiptSectionHTML = document.querySelector('.receipt-section').innerHTML;
      const dataUri = 'data:text/html,' + encodeURIComponent(receiptSectionHTML);
    
      window.open(dataUri, '_blank'); // 在新標簽頁中打開并觸發(fā)打印
    
      // 打印完成后(或者立即),恢復原始HTML,移除注入的腳本
      // 注意:由于是新窗口打開,這里立即恢復對當前頁面DOM沒有影響
      receiptTable.innerHTML = originalReceiptTableHTML; 
    }
    登錄后復制

完整代碼示例

將上述步驟整合,并添加一個按鈕來觸發(fā) printReceipt 函數(shù):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>打印特定元素教程</title>
    <style>
        body {
            font-family: sans-serif;
            margin: 20px;
        }
        .printButton {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            margin-bottom: 20px;
        }
        /* 頁面其他內(nèi)容,確保它不會被打印 */
        .other-content {
            background-color: #f0f0f0;
            padding: 20px;
            border: 1px solid #ccc;
            margin-top: 20px;
        }
    </style>
</head>
<body>

    <h1>網(wǎng)頁特定元素打印示例</h1>
    <button class="printButton">打印收據(jù)</button>

    <div class="other-content">
        這是頁面上的其他內(nèi)容,不應被打印。
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
    </div>

    <section class="receipt-section">
        <table class="receipt">
          <style>
            /* 收據(jù)表格的專用樣式 */
            .receipt {
              border-collapse: collapse;
              max-width: 80%; /* 原始頁面顯示時的最大寬度 */
              font-family: sans-serif;
              width: 100%; /* 打印時通常希望寬度占滿 */
            }

            .receipt td {
              padding: .5em;
            }

            .receipt tr:nth-child(even) {
              border: 1px solid #333;
              border-inline: none;
              background: #ddd;
            }

            .receipt tr:nth-child(odd) {
              background: #fff
            }

            .header-Uprice,
            .item-Uprice,
            .header-qty,
            .item-qty {
              text-align: center
            }

            .total {
              border-bottom: 3px double #000
            }
          </style>
          <tr class="table-headers">
            <td class="header-id">#</td>
            <td class="header-desc">Item Description</td>
            <td class="header-Uprice">Unit Price</td>
            <td class="header-qty">Qty</td>
            <td class="header-price">Price</td>
          </tr>
          <tr class="item" id="1">
            <td class="item-id">1</td>
            <td class="item-desc">Dummy Item1</td>
            <td class="item-Uprice">200$</td>
            <td class="item-qty">1</td>
            <td class="item-price">200$</td>
          </tr>
          <tr class="item" id="2">
            <td class="item-id">2</td>
            <td class="item-desc">Dummy Item2</td>
            <td class="item-Uprice">75$</td>
            <td class="item-qty">1</td>
            <td class="item-price">75$</td>
          </tr>
          <tr class="item" id="3">
            <td class="item-id">3</td>
            <td class="item-desc">Dummy Item3</td>
            <td class="item-Uprice">100$</td>
            <td class="item-qty">2</td>
            <td class="item-price">200$</td>
          </tr>
          <tr class="total">
            <td>Total</td>
            <td></td>
            <td></td>
            <td></td>
            <td>475$</td>
          </tr>
        </table>
    </section>

    <script>
        function printReceipt() {
            const receiptTable = document.querySelector('.receipt');

            // 確保在獲取innerHTML之前,將可能需要居中的樣式注入到新頁面的head中
            // 這里的cssCenteringScript會作為字符串被注入到新頁面的<script>中執(zhí)行
            const cssCenteringScript = `
                const styleTag = document.createElement('style');
                styleTag.innerHTML = '.receipt { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin: 0; max-width: 80%; width: auto; }';
                document.head.appendChild(styleTag);
            `;

            // 保存原始HTML,以便在注入后可以恢復
            const originalReceiptTableHTML = receiptTable.innerHTML;

            // 注入自動打印的腳本到收據(jù)表格內(nèi)容中
            // 這個腳本會在新打開的Data URI頁面中執(zhí)行
            receiptTable.innerHTML += `<script>window.onload = () => { ${cssCenteringScript}; window.print(); };<\/script>`;

            const receiptSectionHTML = document.querySelector('.receipt-section').innerHTML;
            const dataUri = 'data:text/html,' + encodeURIComponent(receiptSectionHTML);

            window.open(dataUri, '_blank'); // 在新標簽頁中打開并觸發(fā)打印

            // 恢復原始HTML,移除注入的腳本,避免影響當前頁面的DOM
            // 這一步在window.open之后立即執(zhí)行,不會影響新打開的Data URI頁面
            receiptTable.innerHTML = originalReceiptTableHTML; 
        }

        const button = document.querySelector('.printButton');
        button.addEventListener('click', printReceipt);
    </script>

</body>
</html>
登錄后復制

注意事項與優(yōu)化

  1. 瀏覽器兼容性:window.open() 和 data: URI 在現(xiàn)代瀏覽器中普遍支持,但某些瀏覽器可能會有對Data URI長度的限制。對于非常大的HTML內(nèi)容,這種方法可能不適用。

    稿定在線PS
    稿定在線PS

    PS軟件網(wǎng)頁版

    稿定在線PS99
    查看詳情 稿定在線PS
  2. 安全性:使用 window.open() 打開 data: URI 通常被認為是安全的,因為內(nèi)容是本地生成的。然而,如果Data URI的內(nèi)容來自不可信的第三方,則可能存在跨站腳本(XSS)風險。在本例中,內(nèi)容來自當前頁面DOM,因此風險較低。

  3. 打印樣式控制 (@media print):對于更專業(yè)的打印布局,推薦使用CSS的 @media print 媒體查詢。通過定義專門的打印樣式表,可以精確控制打印時的頁面布局、字體大小、隱藏非打印元素等,而無需JavaScript的動態(tài)注入。例如:

    /* style.css */
    /* 默認屏幕樣式 */
    .receipt-section { display: block; }
    .print-button { display: block; }
    
    @media print {
        /* 打印時隱藏所有非收據(jù)內(nèi)容 */
        body > *:not(.receipt-section) {
            display: none;
        }
        /* 讓收據(jù)居中 */
        .receipt-section {
            width: 100%;
            margin: auto;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
        /* 確保收據(jù)表格寬度占滿 */
        .receipt {
            width: 100%;
            max-width: none; /* 移除屏幕樣式中的最大寬度限制 */
        }
    }
    登錄后復制

    然后,JavaScript只需調(diào)用 window.print() 即可,無需構建Data URI和注入腳本。這種方法通常更健壯和易于維護。本教程介紹的方法是應對特定場景(如需要完全隔離打印內(nèi)容)的一種靈活變通方案。

  4. 用戶體驗:window.open() 可能會被瀏覽器的彈窗攔截器阻止,尤其是在用戶沒有明確交互(如點擊按鈕)的情況下。確保用戶行為觸發(fā)此函數(shù)可以避免此問題。

總結

通過將特定HTML內(nèi)容封裝為Data URI,并巧妙地利用內(nèi)聯(lián)JavaScript在新頁面加載時觸發(fā) window.print(),我們可以實現(xiàn)一種高效且用戶友好的局部內(nèi)容打印解決方案。雖然這種方法在某些方面可能略顯“非傳統(tǒng)”,但它提供了一種無需復雜DOM操作即可實現(xiàn)局部打印的有效途徑。在實際項目中,開發(fā)者應根據(jù)具體需求權衡其與更標準的 @media print 方案的優(yōu)劣,選擇最適合的實現(xiàn)方式。

以上就是利用JavaScript和Data URI實現(xiàn)網(wǎng)頁特定元素打印教程的詳細內(nèi)容,更多請關注php中文網(wǎng)其它相關文章!

全能打印神器
全能打印神器

全能打印神器是一款非常好用的打印軟件,可以在電腦、手機、平板電腦等設備上使用。支持無線打印和云打印,操作非常簡單,使用起來也非常方便,有需要的小伙伴快來保存下載體驗吧!

下載
來源:php中文網(wǎng)
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權歸原作者所有,本站不承擔相應法律責任。如您發(fā)現(xiàn)有涉嫌抄襲侵權的內(nèi)容,請聯(lián)系admin@php.cn
最新問題
開源免費商場系統(tǒng)廣告
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關于我們 免責申明 意見反饋 講師合作 廣告合作 最新更新
php中文網(wǎng):公益在線php培訓,幫助PHP學習者快速成長!
關注服務號 技術交流群
PHP中文網(wǎng)訂閱號
每天精選資源文章推送
PHP中文網(wǎng)APP
隨時隨地碎片化學習
PHP中文網(wǎng)抖音號
發(fā)現(xiàn)有趣的

Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號