如何使用 C# 从 Dropbox 流式传输 Excel 文件?

How to stream Excel file from Dropbox using C#?

我正在尝试从 Dropbox 流式传输一个 100 MB Excel 文件并写入 SQL 数据库。

我创建了一个 Dropbox API 应用程序并用 C# 代码创建了 Dropbox 客户端。 与 Dropbox 的连接正常,但我在尝试解析 Excel 文档流时遇到错误。

相同的 excel 文件从我的本地机器流式传输时工作正常。

====

代码:

using System;
using System.Data;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Dropbox.Api;
using ExcelDataReader;
using System.Data.SqlClient;

class Program
{
static void Main(string[] args)
{
var task = Task.Run((Func<Task>)Program.Run);
task.Wait();
}

static async Task Run()
{
using (var dbx = new DropboxClient("Access Key"))
{
var full = await dbx.Users.GetCurrentAccountAsync();
Console.WriteLine("{0} - {1}", full.Email, full.Name.DisplayName);

var list = await dbx.Files.ListFolderAsync(string.Empty);

var response = await dbx.Files.DownloadAsync("/Input Files/SampleInputExcelFile.xlsx");

// This Http stream doesn't work
Stream stream1 = await response.GetContentAsStreamAsync();

// This stream does work
Stream stream = File.Open("C:\<PATH>\Input Files\SampleInputExcelFile.xlsx", FileMode.Open, FileAccess.Read);

// This line of code throws the error..
IExcelDataReader reader = ExcelDataReader.ExcelReaderFactory.CreateOpenXmlReader(stream1);

DataSet result = reader.AsDataSet();
//reader.IsFirstRowAsColumnNames = true;
DataTable dt = result.Tables[0];
string text = "'" + dt.Rows[10][0].ToString() + "'" + "," + dt.Rows[10][1].ToString() + "," + dt.Rows[10][2].ToString() + "," + dt.Rows[10][3].ToString();

// SQL steps start from here...
}

}

}

未处理的异常:System.AggregateException:发生一个或多个错误。 (不支持指定的方法。) ---> System.NotSupportedException:不支持指定的方法。 在 System.Net.Http.HttpContentStream.Seek(Int64 偏移量,SeekOrigin 原点) 在 ExcelDataReader.ExcelReaderFactory.CreateOpenXmlReader(Stream fileStream, ExcelReaderConfiguration 配置) 在 C:\projects\exceldatareader\src\ExcelDataReader\ExcelReaderFactory.cs

非常感谢任何帮助! 提前致谢! P.S 我是 C# 的绝对菜鸟,所以请原谅我代码中的天真。

根据您的错误消息,您得到了 NotSupportedException。所以有些东西不受支持。查看您的错误堆栈,您可以看到 CreateOpenXmlReader 正在对 HttpContentStream 调用 Seek,而 Seek 正在抛出 NotSupportedException。所以是 Seek 不受支持。

流可以是 "seekable" 或 "not seekable"。 To "seek" 流是跳到该流中的特定位置。文件流是可搜索的,因为它们代表磁盘上的文件;网络流不可搜索,因为它们代表传输中的数据。

解决此问题的最简单方法是先将文件保存在本地,然后然后使用ExcelReaderFactory打开它。

我能够通过首先将 Http 流复制到内存流中来使其工作。 解决方案如下:

Stream StreamFromDropbox = await response.GetContentAsStreamAsync();         

System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
MemoryStream StreamFromDropboxCopyAsync = new MemoryStream();
await StreamFromDropbox.CopyToAsync(StreamFromDropboxCopyAsync);
StreamFromDropboxCopyAsync.Seek(offset: 0, loc: SeekOrigin.Begin);
IExcelDataReader reader = ExcelDataReader.ExcelReaderFactory.CreateOpenXmlReader(StreamFromDropboxCopyAsync, new ExcelReaderConfiguration() { FallbackEncoding = System.Text.Encoding.GetEncoding(1252) });
DataSet result = reader.AsDataSet();