UWP OpenXML не записывает изменения в SpreadsheetDocument - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть приложение UWP. Я извлек файл Excel из моего диска SharePoint, изменил его на байтовый массив и сохранил на своем жестком диске.

EDIT

Итак, я понял, что файл уже открыт, поэтому не было необходимости открывать его снова. Поэтому я сделал несколько модификаций (весь класс на этот раз):

class FileHelper
{
    public static string saveLocation;
    public static SpreadsheetDocument spreadsheetDoc;

    public static async void GetFileAsync()
    {
        var (authResult, message) = await Authentication.AquireTokenAsync();
        var httpClient = new HttpClient();
        HttpResponseMessage response;
        var request = new HttpRequestMessage(HttpMethod.Get, MainPage.fileurl);
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
        response = await httpClient.SendAsync(request);
        byte[] fileBytes = await response.Content.ReadAsByteArrayAsync();
        StorageLibrary videoLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
        string saveFolder = videoLibrary.SaveFolder.Path;
        string saveFileName = App.Date + "-" + App.StartTime + "-" + App.IBX + "-" + App.Generator + ".xlsx";
        saveLocation = saveFolder + "\\" + saveFileName;

        using (MemoryStream stream = new MemoryStream())
        {
            stream.Write(fileBytes, 0, (int)fileBytes.Length);
            using (spreadsheetDoc = SpreadsheetDocument.Open(stream, true))
            {
                UpdateCell(spreadsheetDoc, App.Date, 2, "D");

                await Task.Run(() =>
                {
                    File.WriteAllBytes(saveLocation, stream.ToArray());
                });
            }
        }           
    }

    public static void UpdateCell(SpreadsheetDocument docName, string text,
        uint rowIndex, string columnName)
    {
        WorksheetPart worksheetPart =
                    GetWorksheetPartByName(spreadsheetDoc, "GenRun");

        if (worksheetPart != null)
        {
            Cell cell = GetCell(worksheetPart.Worksheet,
                                        columnName, rowIndex);

            cell.CellValue = new CellValue(text);
            cell.DataType =
                new EnumValue<CellValues>(CellValues.String);
        }            
    }

    private static WorksheetPart
         GetWorksheetPartByName(SpreadsheetDocument document,
         string sheetName)
    {
        IEnumerable<Sheet> sheets =
           document.WorkbookPart.Workbook.GetFirstChild<Sheets>().
           Elements<Sheet>().Where(s => s.Name == sheetName);

        if (sheets.Count() == 0)
        {
            return null;
        }

        string relationshipId = sheets.First().Id.Value;
        WorksheetPart worksheetPart = (WorksheetPart)
             document.WorkbookPart.GetPartById(relationshipId);
        return worksheetPart;
    }

    private static Cell GetCell(Worksheet worksheet,
              string columnName, uint rowIndex)
    {
        Row row = GetRow(worksheet, rowIndex);

        if (row == null)
            return null;

        return row.Elements<Cell>().Where(c => string.Compare
               (c.CellReference.Value, columnName +
               rowIndex, true) == 0).First();
    }

    private static Row GetRow(Worksheet worksheet, uint rowIndex)
    {
        return worksheet.GetFirstChild<SheetData>().
          Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
    }
}

Записывает файл, но не обновляет файл с помощью ввода данных, вызванного UpdateCell ().

1 Ответ

0 голосов
/ 08 сентября 2018

ОК .... Это то, что я закончил. Это, вероятно, не красиво, но это сработало.

Сначала я изменил событие click, чтобы отделить обновления от передачи файла шаблона.

    private async void FileButton_Click(object sender, RoutedEventArgs e)
    {
        await FileHelper.GetFileAsync();
        await FileHelper.UpdateCell(FileHelper.saveLocation, App.Date, 2, "D");
        await FileHelper.UpdateCell(FileHelper.saveLocation, App.Maximo, 3, "D");
        ...
        await FileHelper.UpdateCell(FileHelper.saveLocation, App.StopHours, 26, "J");
    }

Затем я обновил GetFileAsync () и UpdateCell () для задачи вместо void. Затем, когда я получил ожидающий Task.Run, я добавил возврат TaskStatus.RanToCompletion.

class FileHelper
{
    public static string saveLocation;
    public static SpreadsheetDocument spreadsheetDoc;

    public static async Task GetFileAsync()
    {
        var (authResult, message) = await Authentication.AquireTokenAsync();
        var httpClient = new HttpClient();
        HttpResponseMessage response;
        var request = new HttpRequestMessage(HttpMethod.Get, MainPage.fileurl);
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
        response = await httpClient.SendAsync(request);
        byte[] fileBytes = await response.Content.ReadAsByteArrayAsync();
        StorageLibrary videoLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
        string saveFolder = videoLibrary.SaveFolder.Path;
        string saveFileName = App.Date + "-" + App.StartTime + "-" + App.IBX + "-" + App.Generator + ".xlsx";
        saveLocation = saveFolder + "\\" + saveFileName;

        using (MemoryStream stream = new MemoryStream())
        {
            stream.Write(fileBytes, 0, (int)fileBytes.Length);
            using (spreadsheetDoc = SpreadsheetDocument.Open(stream, true))
            {
                await Task.Run(() =>
                {
                    File.WriteAllBytes(saveLocation, stream.ToArray());
                    return TaskStatus.RanToCompletion;
                });                    
            }
        }           
    }

    public async static Task UpdateCell(string docName, string text,
        uint rowIndex, string columnName)
    {
        StorageLibrary videoLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
        string saveFolder = videoLibrary.SaveFolder.Path;
        string saveFileName = App.Date + "-" + App.StartTime + "-" + App.IBX + "-" + App.Generator + ".xlsx";
        saveLocation = saveFolder + "\\" + saveFileName;

        await Task.Run(() =>
        {
            using (spreadsheetDoc = SpreadsheetDocument.Open(saveLocation, true))
            {
                WorksheetPart worksheetPart =
                    GetWorksheetPartByName(spreadsheetDoc, "GenRun");

                if (worksheetPart != null)
                {
                    Cell cell = GetCell(worksheetPart.Worksheet,
                                                columnName, rowIndex);
                    cell.CellValue = new CellValue(text);
                    cell.DataType =
                        new EnumValue<CellValues>(CellValues.String);

                    worksheetPart.Worksheet.Save();
                }
            }
            return TaskStatus.RanToCompletion;
        });                              
    }

    private static WorksheetPart
         GetWorksheetPartByName(SpreadsheetDocument document,
         string sheetName)
    {
        IEnumerable<Sheet> sheets =
           document.WorkbookPart.Workbook.GetFirstChild<Sheets>().
           Elements<Sheet>().Where(s => s.Name == sheetName);

        if (sheets.Count() == 0)
        {
            return null;
        }

        string relationshipId = sheets.First().Id.Value;
        WorksheetPart worksheetPart = (WorksheetPart)
             document.WorkbookPart.GetPartById(relationshipId);
        return worksheetPart;
    }

    private static Cell GetCell(Worksheet worksheet,
              string columnName, uint rowIndex)
    {
        Row row = GetRow(worksheet, rowIndex);

        if (row == null)
            return null;

        return row.Elements<Cell>().Where(c => string.Compare
               (c.CellReference.Value, columnName +
               rowIndex, true) == 0).First();
    }

    private static Row GetRow(Worksheet worksheet, uint rowIndex)
    {
        return worksheet.GetFirstChild<SheetData>().
          Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
    }
}
...