因此,經過一段時間我的頭撞在桌子上,我決定專注於我的OpenXML Excell調查,我成功了!
我發現一個解決方案如何插入超鏈接到excell文件,甚至更多,現在我的程序可以創建多個表,其數量取決於我的dataObject。 我很興奮,我想和大家分享我的成就。
所有你需要創建SpreadSheetDocument爲此我創建了一個方法CreatePackage的第一和傳遞的參數文件路徑,也是我的數據對象
public void CreatePackage(string filePath, List<DataObject> data)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook)
)
{
CreateParts(document, data);
}
}
它接受
SpreadsheetDocument和
數據對象
CreateParts方法
private void CreateParts(SpreadsheetDocument document, List<DataObject> data)
{
ExtendedFilePropertiesPart extendedFilePropertiesPart = document.AddNewPart<ExtendedFilePropertiesPart>();
extendedFilePropertiesPart.Properties = new Properties();
WorkbookPart workbookPart = document.AddWorkbookPart();
//Create new sheet for every Unique error
GenerateWorkbookPart(workbookPart,data.Count);
//generates new SheetPart for every sheet
GenerateWorkSheetsParts(workbookPart,data);
}
我找不到爲什麼以及如何取決於Excell HyperLink的ExtendedFilePropertiesPart,但我知道確保沒有這個超鏈接不起作用,即使Excell文件也會生成損壞。
接下來,我們需要創建一個工作簿爲WorkBookPart也爲工作簿我們需要創建一個表將舉行所有表。對於每個工作表,我們還需要創建工作簿部分但對於此問題,我會稍後再回來。現在:
private void GenerateWorkbookPart(WorkbookPart workbookPart, int dataCount)
{
Workbook workbook = new Workbook();
Sheets sheets = new Sheets();
Sheet sheet = new Sheet();
for (int i = 1; i < dataCount+2; i++)
{
var relId = "rId" + i;
if (i == 1)
{
sheet = new Sheet()
{
Name = "Main",
SheetId = (uint) i,
Id = relId
};
}
else
{
sheet = new Sheet()
{
Name = "Unique" + (i-1),
SheetId = (uint)i,
Id = relId
};
}
sheets.AppendChild(sheet);
}
workbook.AppendChild(sheets);
workbookPart.Workbook = workbook;
}
爲什麼我在總數中加了+2?因爲首先,由於某種原因,SheetI的RelationshipId(Id)不能爲0,所以我需要從1和第二開始,我excell中的第一頁是導航頁面,所以我也跳過它。
我創造了我的文件WorkBookPart後,我會開始創建WorkSheetPart每個表並用數據填充它。
private void GenerateWorkSheetsParts(WorkbookPart workbookPart, List<DataObject> data)
{
for (int i = 1; i < data.Count+2; i++)
{
var relId = "rId" + i;
if (i == 1)
{
WorksheetPart workSheetPart = workbookPart.AddNewPart<WorksheetPart>(relId);
GenerateWorkSheetPartContent(workSheetPart, i, data);
}
else
{
WorksheetPart workSheetPart = workbookPart.AddNewPart<WorksheetPart>(relId);
GenerateWorkSheetPartContent(workSheetPart, i, data[i-2].NestedObject);
}
}
}
private void GenerateWorkSheetPartContent(WorksheetPart worksheetPart,int indexer, List<NestedObject> data)
{
Worksheet worksheet = new Worksheet();
SheetData sheetData = new SheetData();
Hyperlinks hyperlinks = new Hyperlinks();
if (indexer == 1)
{
sheetData.AppendChild(ConstructHeader("Unique errors", "Count"));
foreach (var @event in data)
{
indexer++;
Row row = new Row();
row.Append(ConstructCell(@event.ErrorMessage, "A" + indexer, CellValues.String), ConstructCell(@event.ListOfErrorsObject.Count.ToString(), CellValues.Number));
sheetData.AppendChild(row);
Hyperlink hyperlink = new Hyperlink()
{
Reference = "A" + indexer,
Location = "Unique" + (indexer - 1)+"!A1",
Display = "Unique" + indexer
};
hyperlinks.AppendChild(hyperlink);
}
worksheet.Append(sheetData, hyperlinks);
worksheetPart.Worksheet = worksheet;
}
else
{
worksheet.AppendChild(sheetData);
worksheetPart.Worksheet = worksheet;
}
}
索引 - 因爲我的對象後,另一個去一個我可以保證索引將是相同擺脫數量,也等於第一列的行號。
我還做了幾個幫手ConstructHeader起初建行頭,它需要字符串和ConstructCell這有助於更快的PARAMS構造,我可以追加到行單元格。它也有一個重載構造應該與超鏈接的單元格。
private Row ConstructHeader(params string[] headers)
{
Row row = new Row();
foreach (var header in headers)
{
row.AppendChild(ConstructCell(header, CellValues.String));
}
return row;
}
private Cell ConstructCell(string value, CellValues dataType)
{
return new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType),
};
}
private Cell ConstructCell(string value, string cellReference, CellValues dataType)
{
return new Cell()
{
CellReference = cellReference,
CellValue = new CellValue(value),
DataType = dataType,
};
}
總結: 此代碼將創建具有第一片材作爲導航和從數據對象填充的數據其它紙張的Excell文檔。我希望這會幫助某人。 另外如果您有任何意見或反饋 - 請分享我想聽到它。