Создать файл Excel с OpenXML, подключенный к базе данных

#c# #sql-server #excel #database #openxml

#c# #sql-сервер #excel #База данных #openxml

Вопрос:

Я хочу создать файл Excel с библиотекой OpenXML. Документ должен быть подключен к базе данных и содержать на одном / нескольких листах разные данные, полученные разными запросами. Пример результата:

 SELECT * FROM dbo.MyTable1 -- data from first table
SELECT * FROM dbo.MyTable2 -- data from second table
  

Документ:
введите описание изображения здесь

Пока у меня есть некоторая рабочая часть кода:

 Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());

            ConnectionsPart connPart = workbookpart.AddNewPart<ConnectionsPart>();
            connPart.Connections = new Connections();

            var connection = new Connection()
            {
                Id = 1,
                Name = "Connection",
                Type = 5, //ODBC
                SaveData = true,
                RefreshOnLoad = true,
                RefreshedVersion = 5,
                MinRefreshableVersion = 1,
                Background = true,
                DatabaseProperties = new DatabaseProperties
                {
                    Connection =
                        "my-connection-string",
                    Command = "SELECT * FROM dbo.MyTable1",
                },
            };

            connPart.Connections.Append(connection);

            QueryTablePart qt = worksheetPart.AddNewPart<QueryTablePart>();

            qt.QueryTable = new QueryTable()
            {
                Name = "Connection",
                ConnectionId = connection.Id,
                AutoFormatId = 16,
                ApplyNumberFormats = true,
                ApplyBorderFormats = true,
                ApplyFontFormats = true,
                ApplyPatternFormats = true,
                ApplyAlignmentFormats = false,
                ApplyWidthHeightFormats = false,
                AdjustColumnWidth = true,
                Headers = false,
                RefreshOnLoad = true
            };

            // Append a new worksheet and associate it with the workbook.
            Sheet sheet = new Sheet()
            {
                Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
                SheetId = 1,
                Name = "mySheet"
            };
            sheets.Append(sheet);
            sheets.Append(qt.QueryTable);

            DefinedNames definedNames = new DefinedNames();
            // Create a new range (name matching the QueryTable name) 
            DefinedName definedName = new DefinedName() { Name = "Connection", Text = "mysheet!$B$2:$B$2",  };

            definedNames.Append(definedName);
            workbookpart.Workbook.Append(definedNames);


            workbookpart.Workbook.Save();
  

Для единственного подключения с помощью одной команды работает нормально. Проблема в том, что я не знаю, как изменить код, чтобы работать с несколькими командами (запросами). Когда я попытался добавить второе соединение и вторую QueryTablePart, документ был создан, но содержимое было повреждено, с ошибкой, в которой говорилось, что для QueryTablePart должен быть один корневой элемент. Кто-нибудь может мне помочь? Спасибо

Ответ №1:

Хорошо, как всегда, я нашел решение самостоятельно. Чтобы все работало правильно, вы должны передать идентификатор QueryTablePart в конструкторе. Часть рабочего кода:

 var connection = new Connection()
            {
                Id = 1,
                Name = "Connection",
                Type = 5, //ODBC
                SaveData = true,
                RefreshOnLoad = true,
                RefreshedVersion = 5,
                MinRefreshableVersion = 1,
                Background = true,
                DatabaseProperties = new DatabaseProperties
                {
                    Connection =
                        "connection-string",
                    Command = "SELECT * FROM dbo.MyTable1",
                },
            };

            var connection1 = new Connection()
            {
                Id = 2,
                Name = "Connection1",
                Type = 5, //ODBC
                SaveData = true,
                RefreshOnLoad = true,
                RefreshedVersion = 5,
                MinRefreshableVersion = 1,
                Background = true,
                DatabaseProperties = new DatabaseProperties
                {
                    Connection =
                        "connection-string",
                    Command = "SELECT * FROM dbo.MyTable2",
                },
            };
            connPart.Connections.Append(connection);
            connPart.Connections.Append(connection1);

            QueryTablePart qt = worksheetPart.AddNewPart<QueryTablePart>("part1");//IMPORTANT
            QueryTablePart qt2 = worksheetPart.AddNewPart<QueryTablePart>("part2");//IMPORTANT

            qt.QueryTable = new QueryTable()
            {
                Name = "Connection",
                ConnectionId = connection.Id,
                AutoFormatId = 16,
                ApplyNumberFormats = true,
                ApplyBorderFormats = true,
                ApplyFontFormats = true,
                ApplyPatternFormats = true,
                ApplyAlignmentFormats = false,
                ApplyWidthHeightFormats = false,
                AdjustColumnWidth = true,
                Headers = false,
                RefreshOnLoad = true
            };
            qt2.QueryTable = new QueryTable()
            {
                Name = "Connection1",
                ConnectionId = connection1.Id,
                AutoFormatId = 16,
                ApplyNumberFormats = true,
                ApplyBorderFormats = true,
                ApplyFontFormats = true,
                ApplyPatternFormats = true,
                ApplyAlignmentFormats = false,
                ApplyWidthHeightFormats = false,
                AdjustColumnWidth = true,
                Headers = false,
                RefreshOnLoad = true
            };

            // Append a new worksheet and associate it with the workbook.
            Sheet sheet = new Sheet()
            {
                Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
                SheetId = 1,
                Name = "mySheet"
            };
            sheets.Append(sheet);
            sheets.Append(qt.QueryTable);
            sheets.Append(qt2.QueryTable);

            DefinedNames definedNames = new DefinedNames();
            // Create a new range (name matching the QueryTable name) 
            DefinedName definedName = new DefinedName() { Name = "Connection", Text = "mysheet!$B$2:$B$2",  };
            DefinedName definedName1 = new DefinedName() { Name = "Connection1", Text = "mysheet!$C$2:$C$2", };

            definedNames.Append(definedName);
            definedNames.Append(definedName1);
            workbookpart.Workbook.Append(definedNames);


            workbookpart.Workbook.Save();