vue3 window.print()局部打印

发布时间:2024年01月16日
<el-button type="primary" @click="toPrint">打 印</el-button>

 <div class="container" id="printcontent">
   <div class="section" >
     	<!-- 打印时图片不展示的情况处理:把获取到的图片转为base64格式  -->
        <img id="imgMsg" :src="ruleForm.imgUrlBase64 ? ruleForm.imgUrlBase64 : ruleForm.imgUrl ? ruleForm.imgUrl : zanWuImg" />
   </div>
 </div>


function toPrint() {
  isPrint.value = true; // 如果打印展示的数据和页面展示的数据不一致,加一个变量来判断当前是打印状态还是展示状态
  window.addEventListener("beforeprint", (event) => {
    // 获取页面打印区域
    window.newstr = document.getElementById("printcontent").innerHTML;
    // 打印的区域赋给body(不是特别友好,打印区域会替换页面body)
    document.body.innerHTML = newstr;
  });
  setTimeout(() => {
    window.print({
      scale: 0.6, // 页面内容展示不全
    });
  }, 800);
  // 由于页面内容被替换,除打印区域外的所有内容包括按钮都会失效,所以页面需要重新加载
  window.onafterprint = () => {
    location.reload();
  }
}


<style>
@media print {
  /* 打印时不展示的内容添加此类名即可 */
  .no-print {
    display: none;
    visibility: hidden;
  }
}
</style>

问题1:打印时图片不展示
解决方案:把获取到的图片转为base64格式

// 把图片转为base64格式
function getBase64(url, callback) {
  console.log('==123url', url)
  var Img = new Image(),
  dataURL = '';
  Img.src = url;
  Img.setAttribute("crossOrigin", 'Anonymous') 
  Img.onload = function () { 
    var canvas = document.createElement("canvas")
    var width = Img.width
    var height = Img.height;
    canvas.width = width;
    canvas.height = height;
    canvas.getContext("2d").drawImage(Img, 0, 0, width, height); 
    dataURL = canvas.toDataURL('image/jpeg'); 
    console.log('把图片转为base64格式dataURL', dataURL)
    callback ? callback(dataURL) : null; 
  };
}

watch(() => props.formData, value => {
  ruleForm.value = value
  getBase64(value.imgUrl, (data) => {
    ruleForm.value = {
      ...ruleForm.value,
      imgUrlBase64: data,
    }
  })
}, {immediate: true, deep: true})

问题2:el-table打印时展示不全
原因:el-table会计算100%宽度为具体多少px 然后再计算出每一列的宽度 通过设置table>colgroup>col 的width属性来设置每一列的宽度。问题是浏览器的打印区域的100%的具体px与打印纸的宽度不一致 所以导致部分区域打印不出来
解决方案:使用原生表格

<table cellspacing="0">
  <tr class="thead"> 
    <td>序号</td>
    <td>姓名</td>
    <td>年龄</td>
    <td>联系电话</td>
    <td>地址</td>
  </tr>
  <template v-if="tableData.length">
    <template v-for="(item, index) in tableData" :key="index">
      <tr>
        <td>{{ item.id }}</td>
        <td>{{ item.name }}</td>
        <td>{{ item.age }}</td>
        <td>{{ item.phone }}</td>
        <td>{{ item.address }}</td>
      </tr>
    </template>
  </template>
  <template v-else>
    <tr>
      <td colspan="5" style="text-align: center;">
        暂无数据
      </td>
    </tr>
  </template>
</table>
<el-pagination
    class="no-print"
    :current-page.sync="form.current"
    :page-size="form.size"
    :total="form.total"
    background
    layout="total,prev, pager, next, jumper"
    @current-change="handleCurrentChange"
    @size-change="handleSizeChange"
/>

table {
  width: 100%;
  border-left: 1px solid #ebeef5;
  border-top: 1px solid #ebeef5;
  font-size: 14px;
  color: #333333;
  .thead {
    background-color: #f8f8f9;
  }
  .text-center {
    text-align: center;
  }
  tr {
    td {
      padding: 8px 12px;
      border-right: 1px solid #ebeef5;
      border-bottom: 1px solid #ebeef5;
    }
  }
}

问题3:页面展示时表格分页展示,打印时展示全部数据
解决方案:加变量控制,判断是否为打印状态,是则请求全部数据

const getData = () => {
  ...
    tableData.value = res.data.records
 ...
}

watch(() => props.isPrint, value => {
  if(value) {
    isPrintValue.value = value;
    form.value.size = 999
    getData()
  }
}, {immediate: true, deep: true})
文章来源:https://blog.csdn.net/qq_45021462/article/details/135623960
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。