使用OpenXML向Excel写入数值后文件为空是什么原因?
核心疑问解答
写入数值不需要SharedStringTablePart这类对应对象,SharedStringTable是专门用来存储重复文本、减小文件体积用的,数值、日期类型可以直接写入CellValue,不需要额外的共享对象。
代码写入失败的核心原因
重复添加Sheets根节点
你打开的是已有的Excel模板,正常的Excel文件Workbook节点下已经存在Sheets集合,你直接执行wrkBook.Workbook.AppendChild(new Sheets())相当于重复添加了Sheets节点,Excel读取文件时会认为结构非法,直接忽略你后续添加的test工作表,你所有写入操作都写到了这个不被识别的工作表里,自然看不到内容。
正确做法是先判断wrkBook.Workbook.Sheets是否为null,为空才创建,不为空直接用已有的Sheets对象。重复添加行对象导致结构冲突
你的AddData方法里先手动执行了wrkSheet.Worksheet.AppendChild(row)创建行,而你用的MSDN官方InsertCellInWorksheet方法本身的逻辑就会先判断指定行索引的行是否存在,不存在会自动创建行插入到SheetData里,你相当于同一个行索引插入了两个Row对象,Excel校验时会判定结构错误,清空对应行的内容。
正确做法是删掉AddData方法里手动创建、插入Row的两行代码,完全用InsertCellInWorksheet的行管理逻辑。未保存并关闭文档对象
你只调用了Worksheet的Save方法,但是Workbook层面的修改(比如新增工作表关联、Sheets集合修改)都还在内存中,没有写入文件,你操作完成后需要调用sprdSheet.Save(),并且调用sprdSheet.Dispose()关闭文档句柄,才能把所有修改刷到本地文件。工作表ID冲突
你手动指定新建Sheet的SheetId为1,如果你打开的模板本身已经存在SheetId=1的工作表,就会出现主键冲突,Excel会直接丢弃你新建的这个test工作表,所有写入内容自然消失。
正确做法是先取现有Sheets里的最大SheetId,加1作为新工作表的SheetId,避免冲突。
内容的提问来源于stack exchange,提问作者FrougeurPro

