首頁 web前端 前端問答 react列印樣式遺失怎麼辦

react列印樣式遺失怎麼辦

Dec 21, 2022 pm 03:45 PM
react

react列印樣式遺失的解決方法:1、透過「npm install --save html2canvas npm install jspdf --save」指令安裝jspdf;2、使用jspdf將需要列印的div轉換成pdf;3、使用react重新列印即可。

react列印樣式遺失怎麼辦

本教學操作環境:Windows10系統、react18版、Dell G3電腦。

react列印樣式遺失怎麼辦?

vue print列印div樣式遺失 (react通用)

使用網路上的print.js插件,列印發現樣式遺失。

解決方案> 將html轉成pdf,再列印pdf

使用jspdf將需要列印的div轉成pdf(轉成的pdf樣式不會遺失,因為pdf.js是將div轉換成canvas)

安裝jspdf

npm install --save html2canvas
登入後複製
npm install jspdf --save
登入後複製

上程式碼

utli.js 直接複製,注意outPutPdf方法入參即可

import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
// base64转blob
export function toBlob(base64Data) {
  let byteString = base64Data
  if (base64Data.split(',')[0].indexOf('base64') >= 0) {
    byteString = atob(base64Data.split(',')[1]); // base64 解码
  } else {
    byteString = unescape(base64Data.split(',')[1]);
  }
  // 获取文件类型
  const mimeString = base64Data.split(';')[0].split(":")[1]; // mime类型
  // ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区
  // let arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
  // let uintArr = new Uint8Array(arrayBuffer) // 创建视图
  const uintArr = new Uint8Array(byteString.length); // 创建视图
  for (let i = 0; i < byteString.length; i += 1) {
    uintArr[i] = byteString.charCodeAt(i);
  }
  // 生成blob
  const blob = new Blob([uintArr], {
    type: mimeString
  })
  // 使用 Blob 创建一个指向类型化数组的URL, URL.createObjectURL是new Blob文件的方法,可以生成一个普通的url,可以直接使用,比如用在img.src上
  return blob;
};
/**
 * 输出pdf
 * @param {*} idName  html元素
 * @param {*} pdfName  输出pdf文件名
 * @param {*} isDownload  是否直接下载
 * @param {*} isPrint 是否直接打印
 * @param {*} callback  执行后的回调  
 */
 export function outPutPdf(idName, pdfName, isDownload = false, isPrint = false, callback) {
  const element = document.getElementById(idName);  // 这个dom元素是要导出的pdf的div容器
  const w = element.offsetWidth;  // 获得该容器的宽
  const h = element.offsetHeight;  // 获得该容器的高
  const offsetTop = element.offsetTop; // 获得该容器到文档顶部的距离  
  const offsetLeft = element.offsetLeft; // 获得该容器到文档最左的距离
  const canvas = document.createElement("canvas");
  let abs = 0;
  const winI = document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条)
  const winO = window.innerWidth; // 获得当前窗口的宽度(包含滚动条)
  if (winO > winI) {
    abs = (winO - winI) / 2; // 获得滚动条宽度的一半
  }
  canvas.width = w * 2; // 将画布宽&&高放大两倍
  canvas.height = h * 2;
  const context = canvas.getContext(&#39;2d&#39;);
  context.scale(2, 2);
  context.translate(-offsetLeft - abs, -offsetTop);
  // 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此translate的时候,要把这个差值去掉
  html2canvas(element, {
    useCORS: true, // 允许加载跨域的图片
    allowTaint: true,
    scale: 2 // 提升画面质量,但是会增加文件大小
  }).then(cs => {
    const contentWidth = cs.width;
    const contentHeight = cs.height;
    // 一页pdf显示html页面生成的canvas高度
    const pageHeight = contentWidth / 592.28 * 841.89;
    // 未生成pdf的html页面高度
    let leftHeight = contentHeight;
    // 页面偏移
    let position = 0;
    // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
    const imgWidth = 595.28;
    const imgHeight = 592.28 / contentWidth * contentHeight;
    const pageDate = cs.toDataURL(&#39;image/jpeg&#39;, 1.0);
    const pdf = new jsPDF(&#39;&#39;, &#39;pt&#39;, &#39;a4&#39;);
    // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面的高度(841.89)
    // 当内容未超过pdf一页显示的范围,无需分页
    if (leftHeight < pageHeight) {
      pdf.addImage(pageDate, &#39;JPEG&#39;, 0, position, imgWidth, imgHeight);
    } else { // 分页
      while (leftHeight > 0) {
        pdf.addImage(pageDate, &#39;JPEG&#39;, 0, position, imgWidth, imgHeight)
        leftHeight -= pageHeight;
        position -= 841.89;
        // 避免添加空白页
        if (leftHeight > 0) {
          pdf.addPage()
        }
      }
    }
    if (isDownload) {
      pdf.save(`${pdfName}.pdf`);
    } 
    if (isPrint) {
      const link = window.URL.createObjectURL(toBlob(pdf.output(&#39;datauristring&#39;)));
            const myWindow = window.open(link);
      myWindow.print();
    }
    callback && callback(pdf);
  })
}
登入後複製

需要列印部分

<div id="printDiv"></div>
登入後複製

vue 全部程式碼

<template>
  <a-modal
    v-model="visible"
    :title="title"
    :maskClosable="false"
    centered
    :width="1000"
    @cancel="close"
  >
    <div id="printDiv">
      <div v-if="!pdfing">
        <span></span>
        <span>入库单</span>
        <a @click="printChart">打印报表</a>
      </div>
      <div class="maintain-view-title pdfing" v-else>
        <span>入库单</span>
      </div>
      <a-form :colon="true" :label-col="{ span: 8 }" :wrapper-col="{ span: 15 }">
        <a-row>
          <a-col :span="8">
            <a-form-item label="入库单号">
              <span>{{ viewInfo.accessNumber }}</span>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="供应商">
              <span>{{ viewInfo.supplier }}</span>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="入库日期">
              <span>{{ viewInfo.accessDate && $moment(viewInfo.accessDate).format(&#39;YYYY-MM-DD HH:mm:ss&#39;) }}</span>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :span="8">
            <a-form-item label="仓库">
              <span>{{ viewInfo.warehouse }}</span>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="来源">
              <span>{{ viewInfo.source }}</span>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="经办人">
              <span>{{ viewInfo.handledBy }}</span>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :span="8">
            <a-form-item label="采购单号">
              <span>{{ viewInfo.purchaseOrderNo }}</span>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="发票号">
              <span>{{ viewInfo.invoiceNo }}</span>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="合同号">
              <span>{{ viewInfo.contractNo }}</span>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :span="8">
            <a-form-item label="入库类型">
              <span>{{ viewInfo.accessType }}</span>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="创建时间">
              <span>{{ viewInfo.addTime }}</span>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item label="备注">
              <span>{{ viewInfo.content }}</span>
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
      <a-table
        style="marginTop: 10px;"
       
        :columns="columns"
        :data-source="data"
        :pagination="false"
        :loading="loading"
        row-key="id"
      >
      </a-table>
    </div>
    <template slot="footer">
      <a-button key="back" type="primary" @click="close">取消</a-button>
    </template>
  </a-modal>
</template>
<script>
import { outPutPdf } from "@/utils/util";
import { getStorageOrderTopDetail, getStorageOrderBottomListNoPage } from "@/api/stock";
export default {
  name: "StockStorageOrderViewModal",
  components: {},
  data() {
    return {
      visible: false,
      form: null,
      title: "出库确认",
      loading: false,
      viewInfo: {},
      columns: [
        {
          title: "序号",
          key: "index",
          customRender: (text, render, index) => {
            return index + 1
          },
          align: "center"
        },
        {
          title: "产品编号",
          key: "productNumber",
          dataIndex: "productNumber"
        },
        {
          title: "类别",
          key: "type",
          dataIndex: "type"
        },
        {
          title: "产品名称",
          key: "productName",
          dataIndex: "productName"
        },
        {
          title: "规格型号",
          dataIndex: "specifications",
          dataIndex: "specifications"
        },
        {
          title: "计量单位",
          key: "unit",
          dataIndex: "unit"
        },
        {
          title: "批次",
          key: "batch",
          dataIndex: "batch"
        },
        {
          title: "数量",
          key: "number",
          dataIndex: "number"
        },
        {
          title: "单价",
          key: "price",
          dataIndex: "price"
        },
        {
          title: "金额",
          key: "total",
          dataIndex: "total"
        },
        {
          title: "已入库",
          key: "inbound",
          dataIndex: "inbound"
        },
        {
          title: "未入库",
          key: "notInbound",
          dataIndex: "notInbound"
        }
      ],
      data: [],
      pdfing: false, // 打印中
    };
  },
  methods: {
    // 显示弹框
    show(id) {
      this.visible = true;
      // 获取上方数据
      getStorageOrderTopDetail({ id }).then(res => {
        if (res.code === 0) {
          this.viewInfo = res.data;
        }
      });
      // 获取下方表格数据
      this.getTableData(id);
    },
    /**
     * 关闭弹框
     */
    close() {
      this.visible = false;
      this.$emit("cancel");
    },
    // 获取表格数据
    getTableData(warehouseRegisterId) {
       const params = {
        warehouseRegisterId
      };
      getStorageOrderBottomListNoPage(params).then(res => {
        this.loading = false;
        if (res.code === 0) {
          this.data = res.data;
        } else {
          this.$common.showErrorMessage(res.msg || "请求出现错误,请稍后再试");
        }
      });
    },
    // 打印
    printChart() {
      this.pdfing = true;
      this.$nextTick(() => {
        outPutPdf(&#39;printDiv&#39;, &#39;入库单&#39;, false, true, () => {
          this.pdfing = false;
        });
      });
    }
  }
};
</script>
<style scoped>
.maintain-view-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  &.pdfing {
    justify-content: center;
  }
  .maintain-view-title-label {
    font-weight: bold;
    font-size: 1.5em;
  }
}
.container-title-block {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
}
.viewForm {
  /deep/.ant-form-item {
    margin-bottom: 0;
  }
}
</style>
登入後複製

推薦學習:《react影片教學

以上是react列印樣式遺失怎麼辦的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何利用React和WebSocket建立即時聊天應用 如何利用React和WebSocket建立即時聊天應用 Sep 26, 2023 pm 07:46 PM

如何利用React和WebSocket建立即時聊天應用程式引言:隨著網路的快速發展,即時通訊越來越受到人們的關注。即時聊天應用程式已成為現代社交和工作生活中不可或缺的一部分。本文將介紹如何利用React和WebSocket建立一個簡單的即時聊天應用,並提供具體的程式碼範例。一、技術準備在開始建立即時聊天應用之前,我們需要準備以下技術和工具:React:一個用於構建

React前後端分離指南:如何實作前後端的解耦與獨立部署 React前後端分離指南:如何實作前後端的解耦與獨立部署 Sep 28, 2023 am 10:48 AM

React前後端分離指南:如何實現前後端的解耦和獨立部署,需要具體程式碼範例在當今的Web開發環境中,前後端分離已經成為一種趨勢。透過將前端和後端程式碼分開,可以讓開發工作更加靈活、高效,並且方便進行團隊協作。本文將介紹如何使用React實現前後端分離,從而實現解耦和獨立部署的目標。首先,我們要先理解什麼是前後端分離。傳統的Web開發模式中,前端和後端是耦合在

如何利用React和Flask建構簡單易用的網路應用 如何利用React和Flask建構簡單易用的網路應用 Sep 27, 2023 am 11:09 AM

如何利用React和Flask建構簡單易用的網路應用引言:隨著網路的發展,網路應用的需求也越來越多樣化和複雜化。為了滿足使用者對於易用性和效能的要求,使用現代化的技術堆疊來建立網路應用變得越來越重要。 React和Flask是兩個在前端和後端開發中非常受歡迎的框架,它們可以很好的結合在一起,用來建立簡單易用的網路應用。本文將詳細介紹如何利用React和Flask

如何利用React和RabbitMQ建立可靠的訊息應用 如何利用React和RabbitMQ建立可靠的訊息應用 Sep 28, 2023 pm 08:24 PM

如何利用React和RabbitMQ建立可靠的訊息傳遞應用程式引言:現代化的應用程式需要支援可靠的訊息傳遞,以實現即時更新和資料同步等功能。 React是一種流行的JavaScript庫,用於建立使用者介面,而RabbitMQ是一種可靠的訊息傳遞中間件。本文將介紹如何結合React和RabbitMQ建立可靠的訊息傳遞應用,並提供具體的程式碼範例。 RabbitMQ概述:

React響應式設計指南:如何實現自適應的前端佈局效果 React響應式設計指南:如何實現自適應的前端佈局效果 Sep 26, 2023 am 11:34 AM

React響應式設計指南:如何實現自適應的前端佈局效果隨著行動裝置的普及和使用者對多螢幕體驗的需求增加,響應式設計成為了現代前端開發的重要考量之一。而React作為目前最受歡迎的前端框架之一,提供了豐富的工具和元件,能夠幫助開發人員實現自適應的佈局效果。本文將分享一些關於使用React實現響應式設計的指南和技巧,並提供具體的程式碼範例供參考。使用React的Fle

React程式碼偵錯指南:如何快速定位與解決前端bug React程式碼偵錯指南:如何快速定位與解決前端bug Sep 26, 2023 pm 02:25 PM

React程式碼偵錯指南:如何快速定位並解決前端bug引言:在開發React應用程式時,經常會遇到各種各樣的bug,這些bug可能會使應用程式崩潰或導致不正確的行為。因此,掌握調試技巧是每個React開發者必備的能力。本文將介紹一些定位和解決前端bug的實用技巧,並提供具體的程式碼範例,幫助讀者快速定位和解決React應用程式中的bug。一、調試工具的選擇:在Re

React Router使用指南:如何實現前端路由控制 React Router使用指南:如何實現前端路由控制 Sep 29, 2023 pm 05:45 PM

ReactRouter使用指南:如何實現前端路由控制隨著單頁應用的流行,前端路由成為了一個不可忽視的重要部分。 ReactRouter作為React生態系統中最受歡迎的路由庫,提供了豐富的功能和易用的API,使得前端路由的實作變得非常簡單和靈活。本文將介紹ReactRouter的使用方法,並提供一些具體的程式碼範例。安裝ReactRouter首先,我們需要

如何利用React和Google BigQuery建立快速的資料分析應用 如何利用React和Google BigQuery建立快速的資料分析應用 Sep 26, 2023 pm 06:12 PM

如何利用React和GoogleBigQuery建立快速的資料分析應用引言:在當今資訊爆炸的時代,資料分析已經成為了各產業中不可或缺的環節。而其中,建構快速、有效率的資料分析應用則成為了許多企業和個人追求的目標。本文將介紹如何利用React和GoogleBigQuery結合來建立快速的資料分析應用,並提供詳細的程式碼範例。一、概述React是用來構建

See all articles