创建文档的方式大致可以分成2种:1.基于现有的模板创建 2.从无到有完全由通过代码生成
选择哪种方式根据自己的需求,如果你的需求中对字体,单元格类型等style要求比较高的话,建议通过模板创建
事先定义好模板,设置好所有的样式,OpenXml只负责把数据填充进去。
现在分别对这两种实现方式进行分析
基于现有的模板创建思路
1.在指定文件夹下定义好Excel文档的template
2.程序运行的时候Copy该模板到另一个目录
File.Copy(reportTemplate, targetFileName, true);
3.OpenXml去填充拷贝后的文档
加载文档
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
{
}
获取要填充的sheet对象这里称为Worksheet
private static Worksheet GetWorksheet(SpreadsheetDocument document, string sheetName)
{
IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName);
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);
if (sheets.Count() == 0)
{
return null;
}
else
return worksheetPart.Worksheet;
}
获取Worksheet中的sheetData 对象
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
sheetData用于存储数据的,通过工具分析可以得到,Excel中所有的行和列都是作为sheetData的element形式存在
往sheetData中填充数据
private static void SetDataIntoSheet(DataTable dt, SheetData sheetData, int sColIndex, int sRowIndex, string header, bool isCal)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
SetVal(j + sColIndex, i + sRowIndex, dt.Rows[i][j], sheetData, dt.Rows[i]);
}
}
//
if (isCal)
SetCalVal(dt.Rows.Count, dt.Columns.Count, 2, sheetData);
SetHeader("A1", sheetData, header);
}
private static void SetVal(int columnIndex, int rowIndex, object cellValue, SheetData sheetData, DataRow dr)
{
IEnumerable<Row> rows = sheetData.Descendants<Row>().Where(r => r.RowIndex.Value == rowIndex);
if (rows.Count() == 0)
{
Row contentRow = CreateDataRow(dr, rowIndex);
sheetData.AppendChild(contentRow);
}
else
{
Row row = rows.First();
IEnumerable<Cell> cells = row.Elements<Cell>().Where(c => c.CellReference.Value == (GetCellReference(columnIndex) + rowIndex));
if (cells.Count() == 0)
return;
else
{
Cell cell = cells.First();
cell.CellValue = new CellValue(cellValue.ToString());
int intValue;
decimal decValue;
if (int.TryParse(cellValue.ToString(), out intValue))
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
else if (decimal.TryParse(cellValue.ToString(), out decValue))
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
else
cell.DataType = new EnumValue<CellValues>(CellValues.String);
}
}
}
创建行
private static Row CreateDataRow(DataRow dataRow, int rowIndex)
{
Row row = new Row { RowIndex = (UInt32)rowIndex };
int intValue;
decimal decValue;
for (int i = 0; i < dataRow.Table.Columns.Count; i++)
{
Cell dataCell;
//value type
if (int.TryParse(dataRow[i].ToString(), out intValue) && dataRow[i].GetType() == typeof(int))
dataCell = CreateValueCell(i + 1, rowIndex, dataRow[i]);
else if (decimal.TryParse(dataRow[i].ToString(), out decValue) && dataRow[i].GetType() == typeof(decimal))
dataCell = CreateValueCell(i + 1, rowIndex, dataRow[i]);
else
dataCell = CreateTextCell(i + 1, rowIndex, dataRow[i]);
row.AppendChild(dataCell);
}
return row;
}
创建单元格并填充数据
private static Cell CreateValueCell(int columnIndex, int rowIndex, object cellValue)
{
Cell cell = new Cell();
cell.DataType = CellValues.Number;
cell.CellReference = GetCellReference(columnIndex);
CellValue value = new CellValue();
value.Text = cellValue.ToString();
cell.AppendChild(value);
return cell;
}
保存workBook
spreadSheet.WorkbookPart.Workbook.Save();