如何使用 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 返回视图。感谢对此的任何帮助。

流量:

  1. 接受视图中的 ID 列表(完成)
  2. 获取这些 ID 的结果(完成)
  3. 构建未获取数据的 ID 列表(完成)、获取 Excel 格式数据的 ID 的报告(完成)以及获取 PDF 格式数据的 ID 的报告(完成)
  4. 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 直到所有文件都处理完毕 允许用户在文件可用时立即下载

执行上述操作不需要任何清理作业或在内存中保存更多文件。