#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();