From 246bf9b8a526839e9b11585c63c21a86f588dfa2 Mon Sep 17 00:00:00 2001 From: KharchenkoVV Date: Wed, 15 Sep 2021 15:22:24 +0500 Subject: [PATCH] Added excel content copying with cell styles --- ConsoleApp1/Program.cs | 62 ++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index 5dfbf7c3..1f80a4af 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -1,15 +1,9 @@ -using AsbCloudApp.Data; -using AsbCloudDb.Model; -using AsbCloudInfrastructure.Services; -using AsbCloudInfrastructure.Services.Cache; -using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; //using AsbSaubReport; //using AutoMapper; -using Microsoft.EntityFrameworkCore; using System; -using System.IO; using System.Linq; namespace ConsoleApp1 @@ -19,6 +13,7 @@ namespace ConsoleApp1 // .Options; //var context = new AsbCloudDbContext(options); + class Program { @@ -29,26 +24,38 @@ namespace ConsoleApp1 using var secondExcel = SpreadsheetDocument.Open(@"D:\excels\excel2.xlsx", true); - using (var resultExcel = SpreadsheetDocument.Create(@"D:\excels\result.xlsx", SpreadsheetDocumentType.Workbook, true)) + using (var resultExcel = SpreadsheetDocument.Create(@"D:\excels\result.xlsx", + SpreadsheetDocumentType.Workbook, true)) { - // Add a WorkbookPart to the document. var workbookPart = resultExcel.AddWorkbookPart(); workbookPart.Workbook = new Workbook(); - // Add a WorksheetPart to the WorkbookPart. var worksheetPart = workbookPart.AddNewPart(); worksheetPart.Worksheet = new Worksheet(); var sheets = workbookPart.Workbook.AppendChild(new Sheets()); - //var sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Test Sheet" }; + var sharedStringTablePart = resultExcel.WorkbookPart. + AddNewPart(); + + var stylesPart = resultExcel.WorkbookPart. + AddNewPart(); + + //var sheet = new Sheet() + //{ + // Id = workbookPart.GetIdOfPart(worksheetPart), + // SheetId = 1, + // Name = "Test Sheet" + //}; //sheets.Append(sheet); workbookPart.Workbook.Save(); } using (var resultExcel = SpreadsheetDocument.Open(@"D:\excels\result.xlsx", true)) { - var resultExcelWorkSheetPart = resultExcel.WorkbookPart.WorksheetParts.First(); - var resultExcelSheetData = resultExcelWorkSheetPart.Worksheet.AppendChild(new SheetData()); + var resultExcelWorkSheetPart = resultExcel.WorkbookPart. + WorksheetParts.First(); + var resultExcelSheetData = resultExcelWorkSheetPart. + Worksheet.AppendChild(new SheetData()); foreach (var sheet in firstExcel.WorkbookPart.Workbook.Descendants()) { @@ -59,14 +66,33 @@ namespace ConsoleApp1 }; resultExcel.WorkbookPart.Workbook.Sheets.Append(newSheet); - var firstExcelWorkSheetPart = firstExcel.WorkbookPart.GetPartById(sheet.Id) as WorksheetPart; // get rows from source - var firstExcelRows = firstExcelWorkSheetPart.Worksheet.Descendants(); // retrieved rows - //var firstExcelRows = sheet.Descendants(); + var firstExcelWorkSheetPart = firstExcel.WorkbookPart. + GetPartById(sheet.Id) as WorksheetPart; + var firstExcelRows = firstExcelWorkSheetPart.Worksheet. + Descendants(); // retrieved rows from source + + // Числовые ячейки хранятся как есть и переносятся без проблем, а вот значения строковых ячеек хранятся + // в отдельной таблице. При этом в самой строковой ячейке хранится индекс этой строки в таблице + // (чтоб не хранить кучу одинаковых строк в документе. Что-то вроде интернирования строк). + // Тут как раз переносится клон этой таблицы из исходного файла в результирующий. + + var firstExcelStringTable = firstExcel.WorkbookPart.GetPartsOfType() + .FirstOrDefault().SharedStringTable; + resultExcel.WorkbookPart.SharedStringTablePart.SharedStringTable = + firstExcelStringTable.CloneNode(true) as SharedStringTable; + + // Аналогично переносим таблицу стилей ячеек (жирный шрифт и прочее). + // Иначе ячейки переносятся абсолютно обычными, без всякой стилизации. + + var stylesSheet = firstExcel.WorkbookPart.GetPartsOfType() + .FirstOrDefault().Stylesheet; + resultExcel.WorkbookPart.WorkbookStylesPart.Stylesheet = + stylesSheet.CloneNode(true) as Stylesheet; + + // Клонируем ряды в новый файл (без клонирования они не вытаскиваются из общего дерева) foreach (var row in firstExcelRows) - { resultExcelSheetData.AppendChild(row.CloneNode(true)); - } } //for (uint i = 1; i < 10; i++) // fills cells fine