问题
I have a number of report-generating ASMX webservices and would like to help our users by adding a link to download a .XLSX file containing a pre-configured and formatted Query Table for the webservice.
They will then be able to build their own graphs and derived reports as they currently do, but also be able to refresh the data without rebuilding everything.
var machStore = IsolatedStorageFile.GetMachineStoreForAssembly();
string fileName = Path.ChangeExtension(Path.GetRandomFileName(), ".xlsx");
using (
IsolatedStorageFileStream ifStream = new IsolatedStorageFileStream(
fileName,
FileMode.CreateNew,
FileAccess.ReadWrite,
FileShare.Read,
machStore
)
)
{
using (
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(
ifStream,
SpreadsheetDocumentType.Workbook
)
)
{
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
ConnectionsPart connPart = workbookpart.AddNewPart<ConnectionsPart>();
connPart.Connections = new Connections();
Connection c = new Connection(){
Id = 1, //should be automatic??
Name = "List",
Type = 4, //Web Query
RefreshedVersion = 4,
MinRefreshableVersion= 1,
Background = false,
SaveData = true,
RefreshOnLoad = true,
WebQueryProperties = new WebQueryProperties()
{
XmlSource = true,
SourceData = true,
ParsePreTag = true,
Consecutive = true,
RefreshedInExcel2000 = true,
Url = "http://server/data/Demand.asmx/List"
}
};
connPart.Connections.Append(c);
QueryTablePart qt = worksheetPart.AddNewPart<QueryTablePart>();
qt.QueryTable = new QueryTable(){
Name="List",
ConnectionId = c.Id,
AutoFormatId = 16,//From where?
ApplyNumberFormats = true,
ApplyBorderFormats = true,
ApplyFontFormats = true,
ApplyPatternFormats = true,
ApplyAlignmentFormats = false,
ApplyWidthHeightFormats = false
};
// 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);
workbookpart.Workbook.Save();
// Close the document.
spreadsheetDocument.Close();
}
ifStream.Position = 0;
response.Clear();
response.AddHeader("content-disposition", "attachment; filename=" + fileName);
response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
ifStream.CopyTo(response.OutputStream);
}
When downloaded, the file does open in Excel 2010, but the query table does not appear as a sheet. The documentation for DocumentFormat.OpenXml
doesn't describe clearly how I should work with instances of the QueryTable
class
回答1:
You need to add
DefinedNames definedNames = new DefinedNames(); //Create the collection
DefinedName definedName = new DefinedName()
{ Name = "List", Text="mysheet!$A$1:$A$1" }; // Create a new range (name matching the QueryTable name)
definedNames.Append(definedName); // Add it to the collection
workbookpart.Workbook.Append(definedNames); // Add collection to the workbook
and remove the line
sheets.Append(qt.QueryTable);
来源:https://stackoverflow.com/questions/17236839/creating-a-querytable-in-an-open-xml-spreadsheet-using-c-sharp