能否打开上传到Blob容器的Excel文件?

时间:2019-02-12 06:29:55

标签: c# azure azure-blob-storage

我正在尝试将数据表的内容以excel格式上载到blob容器中。到目前为止,这是我的代码

System.IO.MemoryStream stream = new System.IO.MemoryStream();
System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
formatter.Serialize(stream, dt); 

var blobContainer = new BlobStorageUtility().GetCloudBlobContainer(StorageConnectionString, SourceContainerName);
var blockBlob = blobContainer.GetBlockBlobReference(ExcelFileName);

blockBlob.Properties.ContentType = "application/vnd.ms-excel";    
blockBlob.UploadFromStream(stream);    
blockBlob.SetProperties(); 

运行代码后,我会在blob容器中找到它

enter image description here

下载文件后,无法打开它。下面是错误

enter image description here

怎么了?

2 个答案:

答案 0 :(得分:1)

在上传到Blob存储之前,应将数据表转换为excel(可以将excel存储在内存中),否则会导致一些错误。

我使用nuget软件包DocumentFormat.OpenXml进行了转换。

主要方法:

        static void Main(string[] args)
        {
            DataTable dt = new DataTable("table1");
            dt.Columns.Add("name",typeof(string));
            dt.Columns.Add("city",typeof(string));
            dt.Columns.Add("gender",typeof(string));

            dt.Rows.Add("jack", "bj", "male");
            dt.Rows.Add("jacky", "sh", "male");
            dt.Rows.Add("iva", "bj", "female");
            dt.Rows.Add("nancy", "wx", "female");
            dt.Rows.Add("ali", "sz", "male");
            dt.Rows.Add("andy", "sz", "male");

            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            using (SpreadsheetDocument document = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
            {
                WriteExcelFile(document, dt);
            }

            CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials("account name", "account key"), true);
            CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
            var cloudBlobContainer = cloudBlobClient.GetContainerReference("test-1");

            var blockBlob = cloudBlobContainer.GetBlockBlobReference("data115.xlsx");
            stream.Position = 0;
            blockBlob.UploadFromStream(stream);

            Console.WriteLine("completed.");
            Console.ReadLine();
        }

转换方法:

       private static void WriteExcelFile(SpreadsheetDocument document, DataTable table)
        {

                WorkbookPart workbookPart = document.AddWorkbookPart();
                workbookPart.Workbook = new Workbook();

                WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                var sheetData = new SheetData();
                worksheetPart.Worksheet = new Worksheet(sheetData);

                Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
                Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Sheet1" };

                sheets.Append(sheet);

                Row headerRow = new Row();

                List<String> columns = new List<string>();
                foreach (System.Data.DataColumn column in table.Columns)
                {
                    columns.Add(column.ColumnName);

                    Cell cell = new Cell();
                    cell.DataType = CellValues.String;
                    cell.CellValue = new CellValue(column.ColumnName);
                    headerRow.AppendChild(cell);
                }

                sheetData.AppendChild(headerRow);

                foreach (DataRow dsrow in table.Rows)
                {
                    Row newRow = new Row();
                    foreach (String col in columns)
                    {
                        Cell cell = new Cell();
                        cell.DataType = CellValues.String;
                        cell.CellValue = new CellValue(dsrow[col].ToString());
                        newRow.AppendChild(cell);
                    }

                    sheetData.AppendChild(newRow);
                }

                workbookPart.Workbook.Save();

        }

测试后,可以正确打开下载的excel:

enter image description here

答案 1 :(得分:0)

由于已经序列化到MemoryStream中,所以位置在流的末尾。通过添加以下内容将其重新设置为开头:

stream.Seek(0, SeekOrigin.Begin);

在完成序列化到流之后。因此,(第一行)代码如下所示:

MemoryStream stream = new System.IO.MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, dt);
stream.Seek(0, SeekOrigin.Begin);
...