I am working on taking an existing Excel File which already has all of its formulas and formatting, I add data to the a sheet with a Table and when I then open that file in Excel I get the error
"Excel completed file level validation and repair. Some parts of this workbook may have been repaired or discarded. Removed Records: Cell information from /xl/worksheets/sheet6.xml part"
I then open a manually created file with the same content and it works just fine. I also discovered the Open XML 2.5 Productivity Tool which when I run validation on the generated file it says no issues found.
When I run a compare on the two files I see the Generated file looks like this.
<x:c r="B462" t="inlineStr">
<x:is>
<x:t>1150828</x:t>
</x:is>
</x:c>
While the Manually created file has Cells that look like this.
<c s="80" r="B462">
<v>
1150828
</v>
</c>
Obviously there is a difference here but I don't know how to correct it nor do I know if this difference is the actual cause of the error. but seeing as how everything else seems to look the same I don't know what else it could be.
Oh and couple more things this file is not working but I am able to use another file that does not contain a Table, when I incorporate a table the issue occurs so I at least know that much.
Also if you're going to suggest that I use ClosedXML please don't. I have used it and it tends to leave off formatting at random for some reason that I cannot figure out hence why I have moved to OpenXML SDk
Here is some of the C# Code
dt.Load(reader);
RowCount = dt.Rows.Count;
ColumnCount = dt.Columns.Count;
workbookPart = spreadDoc.WorkbookPart;
SheetDimension sheetDimension = new SheetDimension() { Reference = "A1:" + ColumnLetters[ColumnCount - 1] + (RowCount + 1) };
worksheetPart = Program.GetWorksheetPart(workbookPart, reportStep.ExcelSheetName);
worksheetPart.Worksheet.SheetDimension = sheetDimension;
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
string relId = workbookPart.Workbook.Descendants<Sheet>().First(s => reportStep.ExcelSheetName.Equals(s.Name)).Id;
if (reportStep.ExcelTableExists)
{
TableDefinitionPart tableDef = null;
int looper = 0;
foreach (WorksheetPart wsp in spreadDoc.WorkbookPart.WorksheetParts)
{
if (wsp.TableDefinitionParts.Where(tbl => tbl.Table.DisplayName.Value.Equals(reportStep.ExcelTableName)).Count() == 1)
{
tableDef = spreadDoc.WorkbookPart.WorksheetParts.ElementAt(looper).TableDefinitionParts.Where(tbl => tbl.Table.DisplayName.Value.Equals(reportStep.ExcelTableName)).FirstOrDefault();
tableDef.Table.Reference.Value = "A1:" + (ColumnLetters[ColumnCount - 1] + (RowCount +1) ).ToString();
tableDef.Table.AutoFilter.Reference.Value = "A1:" + (ColumnLetters[ColumnCount - 1] + (RowCount +1)).ToString();
// tabledefinitionPart = Program.GetTablePart(wsp, reportStep.ExcelTableName, ColumnCount, RowCount);
}
looper++;
}
}
sheetData = Chef.Program.ExportDataTable(dt, sheetData);
Sheet sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == reportStep.ExcelSheetName);
public static TableDefinitionPart GetTablePart(WorksheetPart worksheet, string tablename, int columnCount, int rowCount)
{
uint CellRange = (uint)(columnCount);
TableColumns tableColumns1 = new TableColumns() { Count = (UInt32Value)(CellRange) };
var tableDefPart = worksheet.TableDefinitionParts.Where(tbl => tbl.Table.DisplayName.Value.Equals(tablename)).FirstOrDefault();
//worksheet.WorksheetPart.TableDefinitionParts.AddNewPart<TableDefinitionPart>(tablename);
var table = new Table() { HeaderRowCount = (uint)columnCount, Name = tablename, DisplayName = tablename, Reference = "A1:" + ColumnLetters[columnCount -1] + (rowCount + 1), TotalsRowShown = false };
TableStyleInfo tableStyleInfo1 = new TableStyleInfo()
{
Name = "TableStyleMedium2",
ShowFirstColumn = false,
ShowLastColumn = false,
ShowRowStripes = true,
ShowColumnStripes = false
};
table.Append(tableStyleInfo1);
// table.Append(tableColumns1);
tableDefPart.Table = table;
return tableDefPart;
}
EDIT SECTION ADDING IN THE ADDITIONAL METHODS REQUESTED Updated 9/5/15
I did remove the code that added the header values since they are already a part of the base template of the excel file. also removed the specifying of the cell datatype to preserve what the template already had the cell datatype set to.
public static SheetData ExportDataTable2(System.Data.DataTable exportData, SheetData sheetData)
{
//loop through each data row
DataRow contentRow;
int startRow = 2;
for (int i = 0; i < exportData.Rows.Count; i++)
{
contentRow = exportData.Rows[i];
sheetData.AppendChild(createContentRow(contentRow, i + startRow));
}
return sheetData;
}
private static Cell createTextCell(int columnIndex, int rowIndex, object cellValue)
{
Cell cell = new Cell();
// cell.DataType = CellValues.Number;
cell.CellReference = getColumnName(columnIndex) + rowIndex;
cell.CellValue = new CellValue(cellValue.ToString());
return cell;
}
private static Row createContentRow(DataRow dataRow, int rowIndex)
{
Row row = new Row
{
RowIndex = (UInt32)rowIndex
};
for (int i = 0; i < dataRow.Table.Columns.Count; i++)
{
Cell dataCell = createTextCell(i + 1, rowIndex, dataRow[i]);
// dataCell.DataType = CellValues.SharedString;
row.AppendChild(dataCell);
}
return row;
}
Chef.Program.ExportDataTable
method please? The XML you've listed looks OK; the generated one is using inline strings but the manually created one is using the shared strings table. – Jeanmariejeanna