2017-04-02 1 views
1

OpenXml-SDK를 사용하여 Excel 파일을 다운로드하고 여는 C# Azure 함수를 작성하려고합니다.azure 파일을 다운로드하고 azure 함수로 내용을 읽으십시오.

사무실에 Azure 기능을 사용할 수 없기 때문에 Office Interop이 작동하지 않습니다.

OpenXml-SDK를 사용하여 원격 URL에서 다운로드 한 URL이나 스트림이 아닌 저장된 파일의 경로가 필요한 파일을 열고 읽으려고합니다.

Azure 함수에서 Excel 파일을 임시 저장하는 방법을 모르겠다. Azure File Storage를 사용했다.

url에서 Azure File Storage로 Excel 파일을 업로드했지만 OpenXML-SDK로 Excel 파일을 열 수 없습니다.

Azure File Storage에서 Excel 파일을 테스트했지만 OpenXML.SpreadsheetDocument 양식을 열려고 시도 할 때 MemoryStream이 파일이 손상되었다는 오류가 나타납니다.

Uri (https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-files#develop-with-file-storage) 파일을 전달하는 SpreadsheetDocument를 열려고하면 주소가 260 자 제한을 전달합니다.

OpenXML 이외의 라이브러리를 사용할 수 있으며 이상적으로 Excel 파일을 저장하지 않는 것이 좋습니다.

답변

2

Open XML SDK는 Azure 기능에서 잘 작동합니다. 나는 그것을 내 편에서 시험했다. 여기에 전체 코드가 있습니다. enter image description here

#r "DocumentFormat.OpenXml.dll" 
#r "WindowsBase.dll" 

using System.Net; 
using System.IO; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Spreadsheet; 

public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log) 
{ 
    log.Info($"C# HTTP trigger function processed a request. RequestUri={req.RequestUri}"); 

    WebClient client = new WebClient(); 

    byte[] buffer = client.DownloadData("http://amor-webapp-test.azurewebsites.net/Content/hello.xlsx"); 
    MemoryStream stream = new MemoryStream(); 
    stream.Write(buffer, 0, buffer.Length); 
    stream.Position = 0; 
    using (SpreadsheetDocument doc = SpreadsheetDocument.Open(stream, false)) 
    { 
     WorkbookPart workbookPart = doc.WorkbookPart; 
     SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First(); 
     SharedStringTable sst = sstpart.SharedStringTable; 

     WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); 
     Worksheet sheet = worksheetPart.Worksheet; 

     var cells = sheet.Descendants<Cell>(); 
     var rows = sheet.Descendants<Row>(); 

     log.Info(string.Format("Row count = {0}", rows.LongCount())); 
     log.Info(string.Format("Cell count = {0}", cells.LongCount())); 

     // One way: go through each cell in the sheet 
     foreach (Cell cell in cells) 
     { 
      if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString)) 
      { 
       int ssid = int.Parse(cell.CellValue.Text); 
       string str = sst.ChildElements[ssid].InnerText; 
       log.Info(string.Format("Shared string {0}: {1}", ssid, str)); 
      } 
      else if (cell.CellValue != null) 
      { 
       log.Info(string.Format("Cell contents: {0}", cell.CellValue.Text)); 
      } 
     } 
    } 

    return req.CreateResponse(HttpStatusCode.OK, "Hello "); 
} 

오픈 XML을 사용하려면, 당신은 당신의 기능 폴더 아래에 bin 폴더를 생성하고 그것에 DocumentFormat.OpenXml.dll 및 수 WindowsBase.dll을 업로드했는지 확인하시기 바랍니다.

"File contains corrupted data".

다른 Excel 파일을 사용하여 문제가 특정 Excel 파일과 관련이 있는지 확인해 보았습니까? 코드를 다시 테스트 할 수있는 새로운 간단한 Excel을 만드는 것이 좋습니다.

"It didn't work on my file with the same "File contains corrupted data" message. "

엑셀 파일을 다운로드하고 엑셀 파일의 이전 버전 (.xls)임을 확인했습니다.

예외를 수정하려면 Excel을 최신 버전 (.xlsx)으로 변환하거나 다른 Excel 구문 분석 라이브러리를 선택할 수 있습니다. ExcelDataReader은 모든 Excel 파일 버전에서 작동 할 수 있습니다. 'ExcelDataReader'를 검색하여 NuGet을 사용하여이 라이브러리를 설치할 수 있습니다. 다음은 .xls 형식의 파일을 구문 분석하는 방법에 대한 샘플 코드입니다. Azure Function에서 테스트했는데 정상적으로 작동했습니다.

#r "Excel.dll" 
#r "System.Data" 

using System.Net; 
using System.IO; 
using Excel; 
using System.Data; 

public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log) 
{ 
    log.Info($"C# HTTP trigger function processed a request. RequestUri={req.RequestUri}"); 

    WebClient client = new WebClient(); 

    byte[] buffer = client.DownloadData("http://amor-webapp-test.azurewebsites.net/Content/abcdefg.xls"); 
    MemoryStream stream = new MemoryStream(); 
    stream.Write(buffer, 0, buffer.Length); 
    stream.Position = 0; 

    IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream); 

    DataSet result = excelReader.AsDataSet(); 

    for (int i = 0; i < result.Tables.Count; i++) 
    { 
     log.Info(result.Tables[i].TableName +" has " + result.Tables[i].Rows.Count + " rows."); 
    } 

    return req.CreateResponse(HttpStatusCode.OK, "Hello "); 
} 

은 위의 코드를 실행하기 전에 함수의 bin 폴더에 "Excel.dll"파일을 추가하십시오.

+0

자세한 코드 주셔서 감사합니다. 동일한 "파일에 손상된 데이터가 있음"메시지가 나타나 내 파일에서 작동하지 않습니다. 이 시점에서 내 문제의 Azure 기능 측면이 분명하게 해결되었습니다. 나는 파일을 다운로드하여 Excel에서 열 수있었습니다. 또한 Office interop COM을 사용하여 로컬에서 올바르게 다운로드하고 읽고 구문 분석 할 수있었습니다. 이 시점에서 OpenXML에 대한 질문이있을 수 있습니다. 내 파일을 테스트 할 수 있다면 좋을 것입니다 : http://www2.nationalgrid.com/WorkArea/DownloadAsset.aspx?id=8589936879 또는 OpenXML의 대안을 추천 해 주실 수 있습니다. 감사합니다. – donquijote

+0

의견에 감사드립니다. 귀하의 의견에 따라 답장을 업데이트했습니다. – Amor

+0

이 용도로 설치되지 않은 글꼴은 어떻습니까? –

2

임시 파일을 저장해야하는 경우 Azure 함수에는 임시 폴더에 대한 경로가있는 %TEMP% 환경 변수가 있습니다. 이 폴더는 사용자의 기능을 실행하고 지속되지 않는 VM에 로컬 인 폴더입니다.

그러나 로컬/Azure 파일에 파일을 저장할 필요가 없습니다. 응답 요청에서 스트림을 가져 와서 바로 OpenXML으로 전달할 수 있어야합니다.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(originalExcelUrl); 
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
using (Stream stream = response.GetResponseStream()) 
{ 
    var doc = SpreadsheetDocument.Open(stream, true); 
    // etc 
} 
+0

감사합니다. 붙인 코드를 시도했지만 충돌했습니다. var doc = SpreadsheetDocument.Open (stream, false);을 사용했습니다. originalExcelUrl이 웹 사이트의 링크 인 경우 "true"가 작동하지 않습니다. 오류 메시지 : "검색을 지원하지 않는 스트림에서 작동 할 수 없습니다." 임시 위치에 파일을 저장하지 않기를 바랍니다. 전에이 오류를 본 적이 있습니까? 매우 높이 평가 됨 – donquijote

+0

Temp 변수 접근 방식을 사용하면 파일을 로컬에 저장할 수 있었지만 OpenXML에서 열려고하면 "File has corrupted data"오류가 발생합니다. 그러나 로컬 Temp 폴더에있는 파일이 내가 열 수있는 Excel 파일이라는 것을 알았습니다. 또한 사무실 interop COM을 로컬로 사용할 때도 파일을 열고 읽을 수있었습니다. 이 경우에는 방금 webclient.DownloadFile (theRemoteUrl, theLocalTempFile)을 사용한 다음 SpreadsheetDocument.Open (theLocalTempFile, false)을 다시 사용했습니다. 다시 한 번 감사드립니다! – donquijote

관련 문제