angular - 使用 asp.net core 和 angular 生成下载链接
问题描述
请帮我解决我的问题。
我正在创建一个网站,用户可以上传要转换为 pdf 的 word 文档。并且用户应该能够下载处理后的文件。
到目前为止,我有这个 Html 代码
<input type="file" (change)="upload($event.target.files)" />
Upload Percent: {{percentDone}}% <br />
<ng-container *ngIf="uploadSuccess">
<button type="button">Download</button>
</ng-container>
这是 Angular 代码
upload(files: File[]){
this.uploadAndProgress(files);
}
uploadAndProgress(files: File[]){
console.log(files)
var formData = new FormData();
Array.from(files).forEach(f => formData.append('file',f))
this.http.post('http://localhost:5000/api/DocumentToPdf/Document', formData, {reportProgress: true, observe: 'events'})
.subscribe(event => {
if (event.type === HttpEventType.UploadProgress) {
this.percentDone = Math.round(100 * event.loaded / event.total);
} else if (event instanceof HttpResponse) {
this.uploadSuccess = true;
}
});
}
这是 Asp.net Core 代码
[Route("api/[controller]")]
[ApiController]
public class DocumentToPdfController : ControllerBase
{
private readonly IDocumentToPdf _documentToPdf;
public DocumentToPdfController(IDocumentToPdf documentToPdf)
{
_documentToPdf = documentToPdf;
}
[HttpPost("Document")]
public async Task<Stream> Document()
{
try
{
var file = Request.Form.Files;
return _documentToPdf.DocumentToPdf(file[0].OpenReadStream());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
throw;
}
}
}
我能够处理上传的文件。
但问题是我没有下载输出文件的功能。
截至目前,Asp.net 核心的回归是 Stream。
我怎样才能调整它以能够下载文件过程?
如果我要编写在服务器端处理的文件。如何创建能够下载输出文件的下载链接?
更新:根据 sdev95 评论。我把我的代码改成
控制器:
public HttpResponseMessage Document()
{
try
{
var file = Request.Form.Files;
var fileData = _documentToPdf.DocumentToPdf(file[0].OpenReadStream());
HttpResponseMessage response = null;
response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new ByteArrayContent(fileData.ToArray())
};
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "pdf.pdf";
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentLength = fileData.Length;
Console.WriteLine(fileData.Length);
return response;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
throw;
}
}
还有角码
upload(files: File[]){
this.uploadAndProgress(files);
}
uploadAndProgress(files: File[]){
console.log(files)
var formData = new FormData();
Array.from(files).forEach(f => formData.append('file',f))
this.http.post('http://localhost:5000/api/DocumentToPdf/Document', formData, {reportProgress: true, responseType: 'blob', observe: 'events'})
.subscribe(event => {
if (event.type === HttpEventType.UploadProgress) {
this.percentDone = Math.round(100 * event.loaded / event.total);
} else if (event instanceof HttpResponse) {
this.uploadSuccess = true;
console.log('Success');
console.log('event: ' + event);
this.downloadFile(event, 'download.pdf');
}
});
}
downloadFile(data: any, filename: string) {
const blob = new Blob([data], { type: 'application/octet-stream' });
saveAs(blob, filename);
}
但我现在的问题是。它下载一个文件,但下载的文件只有1kb。
我调试了asp.net核心,代码fileData.Length
返回了类似的东西,49648
但为什么它只返回一个1kb的文件。我的代码有什么问题?
谢谢
解决方案
假设您从后端获取正确的数据。你有几个选择。
在客户端下载文件的几个库选项:
如果您不想使用 3rd 方库,您可以尝试手动执行并从后端返回一个字节数组,那么下面的代码可以工作:)。
示例中的结果是来自后端的响应。
let file = new Blob([result.blob()], {type: 'application/pdf'});
let fileUrl = URL.createObjectURL(file);
var link = document.createElement('a');
link.href = fileUrl;
link.download = "filename___x.pdf";
document.body.appendChild(link);
link.click();
推荐阅读
- python - 尝试将文本文件转换为数据结构
- javascript - 如何根据另一个道具的类型键入对象的道具?
- asp.net - 在 C# 中使用 Web 应用程序保存文档时出错
- javascript - 每次传递新数组时都需要卸载(重新初始化)先前存在的 Howl (Howlerjs)
- java - java流:找到相邻值匹配的最简单方法
- jmeter - JMeter - Api GET 请求 - 响应说:没有已知的方式来呈现数据,虽然状态码是 200
- scala - 如何在 scala 中生成所有列表组合?
- methods - Solidity Function Signature - 关于部分签名的问题
- python - 删除 json 文件中的空字段
- html - 如何将 mat-button 与 mat-input 对齐?