在 JHipster 生成的 Angular 应用程序中,我设法在开发模式下通过 jsPDF 生成 PDF。 但是当我构建它并将其推送到 VPS 上时,在文档中添加图像会导致 web 应用程序崩溃。
717.1183bdcffdb5d922.js:1 ERROR TypeError: Cannot read properties of undefined (reading 'data')
at i.__addimage__.getImageFileTypeByImageData (641.074d6c566f08a36e.js:1:287740)
at Object.Zt (641.074d6c566f08a36e.js:1:295400)
at i.addImage (641.074d6c566f08a36e.js:1:295162)
at m.addImageEntete (287.1ee6c0684b572bd4.js:1:800)
at M.getPDF (641.074d6c566f08a36e.js:1:47054)
at M.generatePDFComplet (641.074d6c566f08a36e.js:1:115186)
at 641.074d6c566f08a36e.js:1:139516
at d7 (717.1183bdcffdb5d922.js:1:217724)
at c (717.1183bdcffdb5d922.js:1:217891)
at HTMLButtonElement.<anonymous> (717.1183bdcffdb5d922.js:1:330709)
我可以在地址栏中显示它们及其 URL。
这是一些相关代码:
import { jsPDF, jsPDFOptions } from 'jspdf';
import autoTable, { RowInput } from 'jspdf-autotable';
export const ENTETE_PATH_ABMS = '/content/images/prints/abms_entete.jpg';
@Injectable({
providedIn: 'root',
})
export class PrintService {
constructor() {}
getPDF() {
const options: jsPDFOptions = {
orientation: 'p',
unit: 'mm',
format: 'a4',
putOnlyUsedFonts: true,
floatPrecision: 16, // or "smart", default is 16
};
const doc = new jsPDF(options);
doc.addImage(ENTETE_PATH_ABMS, 'jpg', posX, posY, w, h);
}
}
我发现这个问题在 jsPDF 中经常出现:我在完全加载图像之前添加了图像,并且该问题出现在生产中,因为他的性能比我的开发计算机低。
在一个著名的聊天机器人的帮助下,我想出了这个解决方案,具有 observables 和 html2canvas。
npm install html2cavas rxjs
在名为 CommonUtils 的实用程序类中:
export type ImageWrapper = {
imagePath : string,
x : number,
y : number,
width : number,
height : number,
}
private static loadImage(url: string): Observable<HTMLImageElement> {
return new Observable((observer) => {
const img = new Image();
img.crossOrigin = 'Anonymous'; // Allow loading images from external URLs
img.onload = () => {
observer.next(img);
observer.complete();
};
img.src = url;
});
}
private static convertImageToCanvas(img: HTMLImageElement, width: number, height: number): Observable<HTMLCanvasElement> {
return from(html2canvas(img, { width, height }));
}
public static addImagesAndSave(images: Array<ImageWrapper>, doc : jsPDF, docname:string): void {
const imageObservables = images.map(({ imagePath }) => this.loadImage(imagePath));
forkJoin(imageObservables)
.pipe(
map((loadedImages) => {
return loadedImages.map((img, index) => {
document.body.appendChild(img);
return this.convertImageToCanvas(img, images[index].width, images[index].height)
}
);
}),
switchMap((canvasObservables) => forkJoin(canvasObservables))
)
.subscribe((canvases) => {
canvases.forEach((canvas, index) => {
const imgData = canvas.toDataURL('image/jpeg');
const { x, y, width, height } = images[index];
console.log('add image ' + ' ' + x + ' ' + y + ' ' + width + ' ' + height + ' ' + imgData )
doc.addImage(imgData, 'PNG', x, y, width, height);
});
doc.save(docname);
});
}
这个服务是这样调用的
var imageList : ImageWrapper[] = []
// set your path , height, width, x and y accordingly
imageList.push({
imagePath : '/assets/images.jpeg',
height : h,
width : w,
x : posX,
y : posY
})
CommonUtils.addImagesAndSave(imageList , doc, 'pdfname.pdf')
由于图像大小问题,我仍然需要进行一些调整,但它们已加载并显示在 pdf 中