You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular点击按钮导出PDF时报nativeElement未定义错误如何解决

Angular项目模态框内容导出PDF报错解决方案

错误原因

你的报错核心是DOM元素引用指向错误,存在两个问题:

  • @ViewChild('output')定义在父组件ServicesComponent中,但#output模板引用变量属于模态框组件AuthLayoutComponent的内部模板,父组件无法直接查询到子组件内部的DOM元素,因此this.output返回值为undefined。
  • 你在submit函数中先执行导出逻辑,再触发模态框打开,此时模态框还未完成渲染,就算引用指向正确也不存在对应DOM节点。

解决方案

步骤1:修改模态框逻辑文件auth-layout.component.ts

在模态框组件内部定义DOM引用和导出PDF方法:

import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Component, Inject, OnInit, ElementRef, ViewChild } from '@angular/core';
import { Invoice } from '../invoice';
import { jsPDF } from "jspdf";

@Component({
  selector: 'app-auth-layout',
  templateUrl: './auth-layout.component.html',
  styleUrls: ['./auth-layout.component.css']
})
export class AuthLayoutComponent implements OnInit {
  // 新增DOM引用查询
  @ViewChild("output", { static: false }) output: ElementRef;
  invoice: Invoice;

  constructor(private dialogRef: MatDialogRef<AuthLayoutComponent>, @Inject(MAT_DIALOG_DATA) data: any) {
    this.invoice = data.invoice;
  }
  ngOnInit(): void {
  }

  // 新增PDF导出方法
  exportPdf() {
    const DATA = this.output.nativeElement;
    const doc: jsPDF = new jsPDF("p", "mm", "a4");
    doc.html(DATA, {
      callback: (doc) => {
        doc.output("dataurlnewwindow");
      }
    });
  }
}

步骤2:修改模态框模板文件auth-layout.component.html

在模板底部新增操作按钮栏,关联导出方法:

<h2 mat-dialog-title>Order Summary</h2>
<div mat-dialog-content id="output" #output>
    <div>
        <strong>Menu items:</strong>
        <div *ngFor="let item of invoice.serviceItems">
            &nbsp;{{ item.serviceName }} ({{item.servicePrice | currency}})
        </div>
        <br />
        Subtotal: {{ invoice.getTotal() | currency }}
    </div>

    <hr />

    <p>
    Labor Cost: {{ invoice.getLaborTotal() | currency }}
    </p>

    <hr />

    <p style="font-weight: bold;">Invoice total: {{ invoice.getInvoice() | currency }}</p>
</div>
<!-- 新增操作栏 -->
<div mat-dialog-actions align="end">
  <button mat-button (click)="exportPdf()">导出PDF</button>
  <button mat-button (click)="dialogRef.close('confirm')">确认</button>
  <button mat-button (click)="dialogRef.close('cancel')">取消</button>
</div>

步骤3:修改父组件services.component.ts

删除无效的引用定义和导出逻辑:

  • 首先删除组件中无效的@ViewChild定义
// 删除这段代码
@ViewChild("output", {
  static: true
}) output: ElementRef;
  • 然后删除submit函数中错误的导出逻辑代码段
// 删除submit函数内的这段代码
//Attempting to create pdf
const DATA = this.output.nativeElement;
const doc: jsPDF = new jsPDF("p", "mm", "a4");
doc.html(DATA, {
  callback: (doc) => {
    doc.output("dataurlnewwindow");
  }
});

修改完成后,点击按钮会先打开模态框渲染发票内容,点击模态框内的导出PDF按钮即可正常导出文件,不会再抛出nativeElement未定义的错误。

内容的提问来源于stack exchange,提问作者john franke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:39:03