如何使用 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();
我正在尝试从 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();