整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          前端頁面如何原樣快速導出PDF?附示例

          何保持頁面樣式基本不變的前提下將HTML頁面導出為PDF,下面提供一些示例代碼,純屬個人原創,如對你有幫助請記得加關注、加收藏、點贊、轉發、分享~謝謝~~

          • 基本思路:保持頁面樣式基本不變,使用 `html2canvas` 將頁面轉換為圖片,然后再通過 `jspdf` 將圖片分頁導出為PDF文件(中間會遇到圖片或文字等內容在分頁處被切割開的問題,如何解決了?詳見末尾干貨)
          • 上基礎代碼:下面為項目中實際代碼截取
          <div>
              <!-- 要打印的內容區 -->
              <div ref="contentRef">
                  <div class="print-item print-out-flow">這是脫離文檔流的內容區域</div>
                  <div class="print-item">這是一行內容,也是最小葉子元素內容</div>
              </div>
              <!-- 打印內容容器 -->
              <div ref="printContainerRef" class="print-container"></div>
          </div>
          /**
            * 1.使用一個隱藏div裝載有滾動條的div.innerHTML
            * 2.隱藏div使用position: absolute, z-index: -999, left: -9999px, width: 900px 控制讓用戶無感知
            * 3.根據需要覆寫隱藏div內html樣式(例如textarea多行顯示有問題, 可以新增一個隱藏的div
            *    包裹textarea的綁定值, 然后在打印樣式中覆寫樣式, 隱藏textarea并顯示對應div)
            */
          handleExport() {
             // 下面是VUE組件內獲取DOM元素代碼,將內容放置到打印區(定義的隱藏DIV)中
              const contentRef = this.$refs.contentRef as HTMLElement;
              const printContainerRef = this.$refs.printContainerRef as HTMLElement;
              // 打印區的需額外處理絕對定位值, 調整使得第一個元素的.top值為0, 以便于頁面計算
              printContainerRef.innerHTML = contentRef.innerHTML;	
              
              // 所有葉子div元素加上 print-item 樣式名, 脫離文檔流的額外添加 print-out-flow
              handlePrintItem(printContainerRef);  // 解決多頁內容可能被切割問題
              
              html2canvas(printContainerRef, {allowTaint: false, useCORS: true}).then((canvas: any) => {
                const contentHeight = canvas.height;
                const contentWidth = canvas.width;
                // pdf每頁顯示的內容高度
                const pageHeight = contentWidth / 595.28 * 841.89;
                // 未生成pdf的頁面高度
                let offsetHeight = contentHeight;
                // 頁面偏移值
                let position = 0;
                // a4紙的尺寸[595.28, 841.89], canvas圖片按a4紙大小縮放后的寬高
                const imgWidth = 595.28;
                const imgHeight = 595.28 / contentWidth * contentHeight;
          
                const dataURL = canvas.toDataURL('image/jpeg', 1.0);
                const doc = new jsPDF('p', 'pt', 'a4');
          
                if (offsetHeight < pageHeight) {
                  doc.addImage(dataURL, 'JPEG', 0, 0, imgWidth, imgHeight);
                } else {
                  while (offsetHeight > 0) {
                    doc.addImage(dataURL, 'JPEG', 0, position, imgWidth, imgHeight);
                    offsetHeight -= pageHeight;
                    position -= 841.89;
          
                    if (offsetHeight > 0) {
                      doc.addPage();
                    }
                  }
                }
          
                doc.save(this.generateReportFileName());
                printContainerRef.innerHTML = '';
              });
          }

          上干貨代碼:上面分頁導出PDF可能網上能看到類型代碼,但絕對找不到下面的代碼,純手搓解決分頁元素被切開問題(思路:獲取自身定位,如自己剛好在被分頁處,則加上一定的margin-top值將內容向下移)

          /** 
           * 處理打印元素項, 修復分頁后被切割的元素
           * @param printContainerRef 打印內容div容器
           * @param itemClassName 打印最小元素標識類名
           * @param outFlowClassName 脫離文檔流的元素標識類名
           */
          export function handlePrintItem(
            printContainerRef: HTMLElement,
            itemClassName: string = 'print-item',
            outFlowClassName: string = 'print-out-flow'
          ): void {
            const rootClientRect = printContainerRef.getBoundingClientRect();
            // 初始化頁面相關數據
            const totalHeight = rootClientRect.height;  // 內容總高度
            const a4PageHeight = (printContainerRef.clientWidth / 595.28) * 841.89; // a4紙高度
            let pageNum = Math.ceil(totalHeight / a4PageHeight);  // 總頁數
            let addPageHeight = 0;  // 修正被分割元素而增加的頁面高度總和
            let currentPage = 1;  // 當前正在處理切割的頁面
            const splitItemObj: { [key: number]: HTMLElement[] } = {};  // 內容中各頁被切割元素存儲對象
          
            const printItemNodes: NodeListOf<HTMLElement> = printContainerRef.querySelectorAll(`.${itemClassName}`);
            for (let item of printItemNodes) {
              // 如果當前頁已經是最后一頁, 則中斷判斷
              if (currentPage >= pageNum) {
                break;
              }
          
              // 獲取元素絕對定位數據
              const clientRect = item.getBoundingClientRect();
              let top = clientRect.top;
              const selfHeight = clientRect.height;
              // 如果當前元素距離頂部高度大于當前頁面頁腳高度, 則開始判斷下一頁頁腳被切割元素
              if (top > currentPage * a4PageHeight) {
                // 換頁前修正上一頁被切割元素
                addPageHeight += fixSplitItems(currentPage, a4PageHeight, splitItemObj[currentPage], outFlowClassName);
                pageNum = Math.ceil((totalHeight + addPageHeight) / a4PageHeight);
                top = item.getBoundingClientRect().top;
                currentPage++;
              }
              // 如果元素剛好處于兩頁之間, 則記錄該元素
              if (top > (currentPage - 1) * a4PageHeight && top < currentPage * a4PageHeight && top + selfHeight > currentPage * a4PageHeight) {
                if (!splitItemObj[currentPage]) {
                  splitItemObj[currentPage] = [];
                }
                splitItemObj[currentPage].unshift(item);
                // 如果當前元素是最后一個元素, 則直接處理切割元素, 否則交由處理下一頁元素時再處理切割
                if (item === printItemNodes[printItemNodes.length - 1]) {
                  fixSplitItems(currentPage, a4PageHeight, splitItemObj[currentPage], outFlowClassName);
                }
              }
            }
          }
          
          /**
            * 修復當前頁所有被切割元素
            * @param currentPage 當前頁
            * @param pageHeight 每頁高度
            * @param splitElementItems 當前被切割元素數組
            * @param outFlowClassName 脫離文檔流的樣式類名
            */
          function fixSplitItems(
            currentPage: number,
            pageHeight: number,
            splitElementItems: HTMLElement[],
            outFlowClassName: string
          ): number {
            if (!splitElementItems || !splitElementItems.length) {
              return 0;
            }
          
            const yMargin = 5;  // y方向距離頁眉的距離
            const splitItemsMinTop = getSplitItemsMinTop(splitElementItems);
            if (!splitItemsMinTop) {
              return 0;
            }
          
            let fixHeight = currentPage * pageHeight - splitItemsMinTop + yMargin;
            const outFlowElement = splitElementItems.find((item) => item.classList.contains(outFlowClassName));
            if (outFlowElement && outFlowElement.parentElement) {
              const parentPreviousElement = outFlowElement.parentElement.previousElementSibling as HTMLElement;
              fixHeight += getMarinTopNum(parentPreviousElement, outFlowElement.parentElement);
              outFlowElement.parentElement.style.marginTop = `${fixHeight}px`;
              return fixHeight;
            }
          
            splitElementItems.forEach((splitElement) => {
              splitElement.style.marginTop = `${fixHeight}px`;
            });
            return fixHeight;
          }
          
          /**
            * 獲取被切割元素數組中最小高度值(如一行有多個元素被切割,則選出距離頂部最小的高度值)
            * @param splitElementItems 當前被切割元素數組
            */
          function getSplitItemsMinTop(
            splitElementItems: HTMLElement[]
          ): number | undefined {
            // 獲取元素中最小top值作為基準進行修正
            let minTop: number | undefined;
            let minElement: HTMLElement | undefined;
            splitElementItems.forEach((splitElement) => {
              let top = splitElement.getBoundingClientRect().top;
              if (minTop) {
                minTop = top < minTop ? top : minTop;
                minElement = top < minTop ? splitElement : minElement;
              } else {
                minTop = top;
                minElement = splitElement;
              }
            });
          
            // 修正當前節點及其前面同層級節點的margin值
            if (minTop && minElement) {
              const previousElement = splitElementItems[splitElementItems.length - 1].previousElementSibling as HTMLElement;
              minTop -= getMarinTopNum(previousElement, minElement);
            }
            return minTop;
          }
          
          /**
            * 通過前一個兄弟元素和元素自身的位置確認一個距離頂部高度修正值
            * @param previousElement 前一個兄弟元素
            * @param curElement 當前元素
            */
          function getMarinTopNum(previousElement: HTMLElement, curElement: HTMLElement): number {
            let preMarginNum = 0;
            let curMarginNum = 0;
            if (previousElement) {
              // 獲取外聯樣式需要getComputedStyle(), 直接.style時對象的值都為空
              const previousMarginBottom = window.getComputedStyle(previousElement).marginBottom;
              preMarginNum = previousMarginBottom ? Number(previousMarginBottom.replace('px', '')) : 0;
            }
            const marginTop = window.getComputedStyle(curElement).marginTop;
            curMarginNum = marginTop ? Number(marginTop.replace('px', '')) : 0;
            return preMarginNum > curMarginNum ? preMarginNum : curMarginNum;
          }

          以上純原創!歡迎加關注、加收藏、點贊、轉發、分享(代碼閑聊站)~

          家好,我是IT共享者,人稱皮皮。這篇文章我們來講講CSS的文本樣式。

          一、文本顏色Color

          顏色屬性被用來設置文字的顏色。

          顏色是通過CSS最經常的指定:

          • 十六進制值 - 如"#FF0000"。
          • 一個RGB值 - "RGB(255,0,0)"。
          • 顏色的名稱 - 如"紅"。

          一個網頁的文本顏色是指在主體內的選擇:

          <html>
              <head>
                  <meta charset="utf-8">
                  <meta name="viewport" content="width=640, user-scalable=no">
                  <title>項目</title>
                  <style>
                      body {
                          color: blue;
                      }
          
          
                      h1 {
                          color: #00ff00;
                      }
          
          
                      h2 {
                          color: rgb(255, 0, 0);
                      }
          </style>
              </head>
          
          
              <body>
                  <h2>hello world</h2>
                  <h1>welcome to CaoZhou</h1>
              </body>
          
          
          </html>

          注:對于W3C標準的CSS:如果你定義了顏色屬性,你還必須定義背景色屬性。


          二、屬性

          1. text-align 文本的對齊方式

          文本排列屬性是用來設置文本的水平對齊方式。

          文本可居中或對齊到左或右,兩端對齊。

          當text-align設置為"justify",每一行被展開為寬度相等,左,右外邊距是對齊(如雜志和報紙)。

          <!doctype html>
          <html lang="en">
          
          
              <head>
                  <meta charset="UTF-8">
                  <title>Document</title>
                  <style>
                      h1 {
                          text-align: center;
                      }
          
          
                      p.date {
                          text-align: right;
                      }
          
          
                      p.main {
                          text-align: justify;
                      }
          </style>
              </head>
          
          
              <body>
          
          
                  <p class="date">2015 年 3 月 14 號</p>
                  <p class="main"> 從前有個書生,和未婚妻約好在某年某月某日結婚。到那一天,未婚妻卻嫁給了別人。書生受此打擊, 一病不起。  這時,路過一游方僧人,從懷里摸出一面鏡子叫書生看。書生看到茫茫大海,一名遇害的女子一絲不掛地躺在海灘上。路過一人, 看一眼,搖搖頭,走了。又路過一人,將衣服脫下,給女尸蓋上,走了。再路過一人,過去,挖個坑,小心翼翼把尸體掩埋了。  僧人解釋道, 那具海灘上的女尸,就是你未婚妻的前世。你是第二個路過的人,曾給過他一件衣服。她今生和你相戀,只為還你一個情。但是她最終要報答一生一世的人,是最后那個把她掩埋的人,那人就是他現在的丈夫。書生大悟,病愈。
          
          
                  </p>
                  <p><b>注意:</b> 重置瀏覽器窗口大小查看 "justify" 是如何工作的。</p>
              </body>
          
          
          </html>

          2. text-decoration文本修飾

          text-decoration 屬性用來設置或刪除文本的裝飾。

          從設計的角度看 text-decoration屬性主要是用來刪除鏈接的下劃線:

          <!doctype html>
          <html lang="en">
          
          
              <head>
                  <meta charset="UTF-8">
                  <title>Document</title>
                  <style>
                      .none {}
          
          
                      .del {
                          text-decoration: none;
                      }
          </style>
              </head>
          
          
              <body>
                  <p>原來的樣子</p>
                  <a href="#" class="none">wwwwwwwwwwwwwwwwww</a>
                  <p>去掉下劃線</p>
                  <a href="#" class="del">wwwwwwwwwwwwwwwwwwwww</a>
              </body>
          
          
          </html>

          也可以這樣裝飾文字:

          <html>
              <head>
                  <meta charset="utf-8">
                  <meta name="viewport" content="width=640, user-scalable=no">
                  <title>項目</title>
                  <style>
                      h1 {
                          text-decoration: overline;
                      }
          
          
                      h2 {
                          text-decoration: line-through;
                      }
          
          
                      h3 {
                          text-decoration: underline;
                      }
          </style>
              </head>
          
          
              <body>
                  <h1>This is heading 1</h1>
                  <h2>This is heading 2</h2>
                  <h3>This is heading 3</h3>
              </body>
          
          
          </html>

          注:不建議強調指出不是鏈接的文本,因為這常常混淆用戶。


          3. text-transform文本轉換

          text-transform文本轉換屬性是用來指定在一個文本中的大寫和小寫字母。

          • uppercase:轉換為全部大寫。
          • lowercase:轉換為全部小寫。
          • capitalize :每個單詞的首字母大寫。
          <!DOCTYPE html>
          <html>
          
          
              <head>
                  <meta charset="utf-8">
                  <meta name="viewport" content="width=640, user-scalable=no">
                  <title>項目</title>
                  <style>
                      p.uppercase {
                          text-transform: uppercase;
                      }
          
          
                      p.lowercase {
                          text-transform: lowercase;
                      }
          
          
                      p.capitalize {
                          text-transform: capitalize;
                      }
          </style>
              </head>
          
          
              <body>
                  <p class="uppercase">This is some text.</p>
                  <p class="lowercase">This is some text.</p>
                  <p class="capitalize">This is some text.</p>
              </body>
          
          
          </html>

          4. text-indent文本縮進

          text-indent文本縮進屬性是用來指定文本的第一行的縮進。

          p {text-indent:50px;}

          5. letter-spacing 設置字符間距

          增加或減少字符之間的空間。

          <style>
               h1 {
                 letter-spacing:2px;
          }
                h2 {
                  letter-spacing:-3px;
          }
          </style>

          6. line-height設置行高

          指定在一個段落中行之間的空間。

          <html>
              <head>
                  <meta charset="utf-8">
                  <meta name="viewport" content="width=640, user-scalable=no">
                  <title>項目</title>
                  <style>
                      p.small {
                          line-height: 70%;
                      }
          
          
                      p.big {
                          line-height: 200%;
                      }
          </style>
              </head>
          
          
              <body>
                  <p>
                      This is a paragraph with a standard line-height.<br> This is a paragraph with a standard line-height.<br> The default line height in most browsers is about 110% to 120%.<br>
                  </p>
          
          
                  <p class="small">
                      This is a paragraph with a smaller line-height.<br> This is a paragraph with a smaller line-height.<br> This is a paragraph with a smaller line-height.<br> This is a paragraph with a smaller line-height.<br>
                  </p>
          
          
                  <p class="big">
                      This is a paragraph with a bigger line-height.<br> This is a paragraph with a bigger line-height.<br> This is a paragraph with a bigger line-height.<br> This is a paragraph with a bigger line-height.<br>
                  </p>
          
          
              </body>
          
          
          </html>

          7. word-spacing 設置字間距

          增加一個段落中的單詞之間的空白空間。

          <html>
              <head>
                  <meta charset="utf-8">
                  <meta name="viewport" content="width=640, user-scalable=no">
                  <title>項目</title>
                  <style type="text/css">
                      p {
                          word-spacing: 30px;
                      }
          </style>
              </head>
          
          
              <body>
          
          
                  <p>
                      This is some text. This is some text.
                  </p>
          
          
              </body>
          
          
          </html>

          8. vertical-align 設置元垂直居中

          設置文本的垂直對齊圖像。

          <html>
              <head>
                  <meta charset="utf-8">
                  <meta name="viewport" content="width=640, user-scalable=no">
                  <title>項目</title>
                  <style>
                      img{
                          width: 200px;
                          height: 100px;
                      }
                      img.top {
                          vertical-align: text-top;
          
          
                      }
          
          
                      img.bottom {
                          vertical-align: text-bottom;
          
          
                      }
          </style>
              </head>
          
          
              <body>
                  <p>An <img src="img/logo.png"  /> image with a default alignment.</p>
                  <p>An <img class="top" src="img/logo.png" /> image with a text-top alignment.</p>
                  <p>An <img class="bottom" src="img/logo.png" /> image with a text-bottom alignment.</p>
              </body>
          
          
          </html>

          9. text-shadow 設置文本陰影

          設置文本陰影。

          <html>
              <head>
                  <meta charset="utf-8">
                  <meta name="viewport" content="width=640, user-scalable=no">
                  <title>項目</title>
                  <style>
                   h1{
                      text-shadow: 2px 2px #FF0000;
               }
          </style>
              </head>
          
          
              <body>
              <h1>Text-shadow effect</h1>
              </body>
          
          
          </html>

          三、總結

          本文主要介紹了CSS文本樣式實際應用中應該如何去操作,通過講解文本中對應的屬性去改變文本的表現形式。使用豐富的效果圖的展示,能夠更直觀的看到運行的效果,能夠更好的理解。使用Html語言,代碼結構更佳的清晰,能夠幫助你更好的學習。

          、行級標簽轉換為塊級標簽

          轉換為塊級標簽,各自獨占一行,且可以設置寬高

          代碼:<a href="">我是a標簽</a>

          <a href="">我是a標簽</a>

          <a href="">我是a標簽</a>

          CSS :display:block;

          width: 100px;

          height: 30px;

          border: 1px solid black;

          在瀏覽器中的樣式:

          二、塊級標簽轉換為行級標簽

          轉化為行級標簽,共同占一行,不能設置寬高

          代碼:<h3>我是塊級標簽</h3>

          <h3>我是塊級標簽</h3>

          <h3>我是塊級標簽</h3>

          CSS:display: inline;

          width: 200px;

          height: 100px;

          border: 1px solid red;

          在瀏覽器中的樣式:

          三、轉化為行內塊級標簽

          能共占一行,而且可以設置各自的寬高

          1.行級元素轉化為行內塊級元素

          代碼:<a class="a1" href="">我是a標簽</a>

          <a class="a2" href="">我是a標簽</a>

          CSS: a{ display:inline-block; border: 1px solid black; }

          .a1{width: 100px; height: 30px; }

          .a2{ width: 50px; height: 50px; }

          在瀏覽器中的樣式:

          2.塊級標簽轉化為行內塊級標簽

          代碼:<h3 class="h3_1">我是塊級標簽</h3>

          <h3 class="h3_2">我是塊級標簽</h3>

          CSS:h3{display: inline-block;border: 1px solid red;}

          .h3_1{width: 100px;height: 100px;}

          .h3_2{width: 200px;height: 50px;}

          在瀏覽器中的樣式:

          四、display的另一個屬性,可以將元素隱藏

          display:none;

          如果想了解更多塊級標簽和行內標簽的屬性,請關注,參看上一篇文章,有寫的不對或不全面的地方,請大家多多指出。


          主站蜘蛛池模板: 伊人久久精品一区二区三区| 波多野结衣高清一区二区三区 | 国产一区二区三区高清在线观看| 少妇一夜三次一区二区| 韩国一区二区三区视频| 视频一区二区在线观看| 无码国产伦一区二区三区视频| 日韩免费无码一区二区视频| 一区二区三区视频在线| 台湾无码一区二区| 麻豆aⅴ精品无码一区二区| 精品一区二区视频在线观看| 无码av免费毛片一区二区| 国产成人一区二区在线不卡| 精品福利一区二区三| 在线观看一区二区三区av| 日本中文字幕在线视频一区| 国产在线无码视频一区二区三区| 亚洲影视一区二区| 成人在线视频一区| 中文字幕人妻无码一区二区三区| 国产在线一区二区在线视频| 亚洲老妈激情一区二区三区| 午夜福利一区二区三区在线观看 | 国偷自产一区二区免费视频| 日韩精品成人一区二区三区| 亚洲国产精品第一区二区| 无码国产伦一区二区三区视频| 无码人妻精品一区二区在线视频 | 伊人色综合一区二区三区| 国产午夜精品片一区二区三区| ...91久久精品一区二区三区| 国产品无码一区二区三区在线| 精品久久一区二区三区| 国产一区二区视频在线观看| 怡红院AV一区二区三区| 亚洲乱码一区二区三区在线观看| 国产一区二区三区美女| 国产午夜精品一区理论片飘花| 97人妻无码一区二区精品免费 | 国产成人免费一区二区三区|