如何实现自定义文件名的PDF新标签预览及指定文件名下载
解决方案
浏览器生成的Blob URL(带UUID格式)无法直接修改为带自定义文件名的格式,但可以通过将Blob转换为File对象来实现预览后按指定文件名下载的需求——File对象包含文件名属性,浏览器PDF预览器的下载按钮会自动使用这个文件名。
步骤1:修改previewPDF方法,支持返回带文件名的File对象
调整方法,新增文件名参数,将Blob转换为File返回:
previewPDF(url: string, fileName: string): Promise<File> { return this.http.get(url, { responseType: 'blob' }).toPromise().then( (res) => { // 将Blob转换为File对象,指定文件名与MIME类型 return new File([res], fileName, { type: 'application/pdf' }); }); }
步骤2:调整previewInfoPDF方法,传入文件名并处理预览
调用previewPDF时传入info中的文件名,基于File对象创建Blob URL:
previewInfoPDF() { const promises = this.previewInfo.map(async info => { // 传入info中的文件名(需确保info包含fileName字段,可根据实际数据结构调整) return this.apiSvc.previewPDF(info.url, info.fileName); }); Promise.all(promises).then(results => { results.forEach(file => { const fileURL = URL.createObjectURL(file); const newTab = window.open(fileURL, '_blank'); // 新标签页加载完成后释放Blob URL,避免内存泄漏 newTab?.addEventListener('load', () => { URL.revokeObjectURL(fileURL); }); }); }); }
关键说明
- File对象继承自Blob,
URL.createObjectURL可正常处理,生成的URL仍为UUID格式,但浏览器会识别File的name属性,点击PDF预览器的下载按钮时会自动使用该文件名保存。 - 务必在新标签页加载完成后调用
URL.revokeObjectURL释放资源,防止内存泄漏。 - 确保
this.previewInfo中的每个info对象包含fileName字段(如info.fileName = "合同文件.pdf"),若文件名来自后端,可从响应头或接口返回数据中提取。
备选方案:自定义预览页面控制下载行为
如果需要完全自定义预览页的下载逻辑,可创建包含PDF预览组件和自定义下载按钮的临时HTML页面:
previewInfoPDF() { const promises = this.previewInfo.map(async info => { const blob = await this.apiSvc.previewPDF(info.url); return { blob, fileName: info.fileName }; }); Promise.all(promises).then(items => { items.forEach(item => { const fileURL = URL.createObjectURL(item.blob); // 构建自定义预览页面的HTML内容 const html = ` <!DOCTYPE html> <html> <head> <title>PDF预览</title> <style> body { margin: 0; } embed { width: 100vw; height: 100vh; } .download-btn { position: fixed; top: 20px; right: 20px; padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; } </style> </head> <body> <embed src="${fileURL}" type="application/pdf"> <button class="download-btn" onclick="downloadFile()">下载</button> <script> function downloadFile() { const a = document.createElement('a'); a.href = "${fileURL}"; a.download = "${item.fileName}"; a.click(); } // 页面关闭时释放Blob URL window.addEventListener('unload', () => { URL.revokeObjectURL("${fileURL}"); }); </script> </body> </html> `; // 创建HTML的Blob URL并打开新标签页 const htmlBlob = new Blob([html], { type: 'text/html' }); const htmlURL = URL.createObjectURL(htmlBlob); window.open(htmlURL, '_blank'); }); }); }
这种方式可完全自定义预览页的布局与下载行为,确保下载文件名符合需求。
内容的提问来源于stack exchange,提问作者Myat Thiha
相关产品推荐
相关产品推荐

