如何使用 ASP.NET MVC 为 Razor 视图生成并 return 包含附加数据的多个文件?
How do I generate and return multiple files with additional data to Razor views using ASP.NET MVC?
我的 Controller/Action 从视图中接收了一些 ID(通过 Post)。
对于每个 ID,将获取一个文件。我需要 return 一些生成的 Excel 或 PDF 文件以及未获取任何结果的 ID 列表。用户可以下载任何生成的文件。
我已准备好构建失败 ID 列表以及 Excel 和 PDF 报告的所有逻辑,但我不确定如何 return 返回视图。感谢对此的任何帮助。
流量:
- 接受视图中的 ID 列表(完成)
- 获取这些 ID 的结果(完成)
- 构建未获取数据的 ID 列表(完成)、获取 Excel 格式数据的 ID 的报告(完成)以及获取 PDF 格式数据的 ID 的报告(完成)
- Return 第 3 步中构建的工件 (需要帮助)
Post 可以是 Ajax 和非 ajax。我猜你没有做 Ajax post.
将文件从控制器发送到视图更容易。但是,您打算如何根据用户的选择交付文件?视图由 Html、CSS 和 javascript 组成。所以你必须想办法为你持有的二进制数据提供服务。
既然您将文件保存在内存中,那么为什么不将文件作为二进制数据发送到视图呢?
以下是如何将文件发送到视图的代码示例:
型号:
public class MyModel
{
Public List<MyFile> files { get; post; }
Public int TotalFilesProcessed { get; post; }
Public int TotalFilesFailed { get; post; }
}
public class MyFile
{
Public string FileName { get; post; }
Public string FileExtension { get; post; }
Public byte[] FileContent { get; post; }
Public double FileLength { get; post; }
Public double ContentType { get; post; }
}
Controller/Action:
MyModel model = new MyModel();
MyModel.files = new List<MyFile>();
MyFile file1 = new MyFile();
file1.FileExtension = "pdf"
file1.FileContent = null; //Assign file byte from the memory
file1.FileLength = file1.FileContent.Length;
file1.ContentType = "application/octet-stream";
MyModel.files.Add(file1);
MyFile file2 = new MyFile();
file2.FileExtension = "png"
file2.FileContent = null; //Assign file byte from the memory
file2.FileLength = file2.FileContent.Length;
file2.ContentType = "application/octet-stream";
MyModel.files.Add(file2);
MyModel.TotalFilesProcessed = 5;
MyModel.TotalFilesFailed = 2;
return View(model);
在剃须刀视图上,您可以编写 C# 代码以从模型中获取数据。遍历 List<MyFile>
并将文件名呈现为 Html 按钮或超链接,以便用户可以单击一个并下载文件。
根据您的问题,您可以将文件发送到视图。但真正的问题应该是当用户点击一个按钮时,你如何将字节传送给用户。
以下是一段代码,可帮助您将字节放入 javascript 代码中。阅读代码详情:
var bytes = new Uint8Array(resultByte); // pass your byte response to this constructor
var blob=new Blob([bytes], {type: "application/pdf"});// change resultByte to bytes
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="myFileName.pdf";
link.click();
这里的概念是从html页面传输字节,以便浏览器触发内容的文件下载。您需要根据需要调整 js。
注:
我认为提前准备文件并保存在内存中不是一个好主意。
相反,您为什么不准备一个可以从页面 (javascript) 使用参数调用的部分操作。然后此部分操作将根据您的输入准备一个文件并将 byte/status 发送到视图。
根据状态,您可以决定是允许下载文件还是显示状态消息。
推荐流程如下:
- 进行部分操作,该操作采用一个 ID 并为此处理文件。如果未找到数据,则发送 404 json 结果。
- 对于所有 ID,循环调用部分操作并在您的 jabascript 中收集所有响应
- 一旦获得所有结果(或者甚至每个 ajax 响应都出现),您可以在 UI.[=58= 中为此添加一个 button/hyperlink ]
- 在 UI 上显示加载程序,以便用户知道正在处理文件。您可以选择阻止 UI 直到所有文件都处理完毕 允许用户在文件可用时立即下载
执行上述操作不需要任何清理作业或在内存中保存更多文件。
我的 Controller/Action 从视图中接收了一些 ID(通过 Post)。
对于每个 ID,将获取一个文件。我需要 return 一些生成的 Excel 或 PDF 文件以及未获取任何结果的 ID 列表。用户可以下载任何生成的文件。
我已准备好构建失败 ID 列表以及 Excel 和 PDF 报告的所有逻辑,但我不确定如何 return 返回视图。感谢对此的任何帮助。
流量:
- 接受视图中的 ID 列表(完成)
- 获取这些 ID 的结果(完成)
- 构建未获取数据的 ID 列表(完成)、获取 Excel 格式数据的 ID 的报告(完成)以及获取 PDF 格式数据的 ID 的报告(完成)
- Return 第 3 步中构建的工件 (需要帮助)
Post 可以是 Ajax 和非 ajax。我猜你没有做 Ajax post.
将文件从控制器发送到视图更容易。但是,您打算如何根据用户的选择交付文件?视图由 Html、CSS 和 javascript 组成。所以你必须想办法为你持有的二进制数据提供服务。
既然您将文件保存在内存中,那么为什么不将文件作为二进制数据发送到视图呢?
以下是如何将文件发送到视图的代码示例:
型号:
public class MyModel
{
Public List<MyFile> files { get; post; }
Public int TotalFilesProcessed { get; post; }
Public int TotalFilesFailed { get; post; }
}
public class MyFile
{
Public string FileName { get; post; }
Public string FileExtension { get; post; }
Public byte[] FileContent { get; post; }
Public double FileLength { get; post; }
Public double ContentType { get; post; }
}
Controller/Action:
MyModel model = new MyModel();
MyModel.files = new List<MyFile>();
MyFile file1 = new MyFile();
file1.FileExtension = "pdf"
file1.FileContent = null; //Assign file byte from the memory
file1.FileLength = file1.FileContent.Length;
file1.ContentType = "application/octet-stream";
MyModel.files.Add(file1);
MyFile file2 = new MyFile();
file2.FileExtension = "png"
file2.FileContent = null; //Assign file byte from the memory
file2.FileLength = file2.FileContent.Length;
file2.ContentType = "application/octet-stream";
MyModel.files.Add(file2);
MyModel.TotalFilesProcessed = 5;
MyModel.TotalFilesFailed = 2;
return View(model);
在剃须刀视图上,您可以编写 C# 代码以从模型中获取数据。遍历 List<MyFile>
并将文件名呈现为 Html 按钮或超链接,以便用户可以单击一个并下载文件。
根据您的问题,您可以将文件发送到视图。但真正的问题应该是当用户点击一个按钮时,你如何将字节传送给用户。
以下是一段代码,可帮助您将字节放入 javascript 代码中。阅读代码详情
var bytes = new Uint8Array(resultByte); // pass your byte response to this constructor
var blob=new Blob([bytes], {type: "application/pdf"});// change resultByte to bytes
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="myFileName.pdf";
link.click();
这里的概念是从html页面传输字节,以便浏览器触发内容的文件下载。您需要根据需要调整 js。
注:
我认为提前准备文件并保存在内存中不是一个好主意。
相反,您为什么不准备一个可以从页面 (javascript) 使用参数调用的部分操作。然后此部分操作将根据您的输入准备一个文件并将 byte/status 发送到视图。
根据状态,您可以决定是允许下载文件还是显示状态消息。
推荐流程如下:
- 进行部分操作,该操作采用一个 ID 并为此处理文件。如果未找到数据,则发送 404 json 结果。
- 对于所有 ID,循环调用部分操作并在您的 jabascript 中收集所有响应
- 一旦获得所有结果(或者甚至每个 ajax 响应都出现),您可以在 UI.[=58= 中为此添加一个 button/hyperlink ]
- 在 UI 上显示加载程序,以便用户知道正在处理文件。您可以选择阻止 UI 直到所有文件都处理完毕 允许用户在文件可用时立即下载
执行上述操作不需要任何清理作业或在内存中保存更多文件。