我正在使用OpenXml SDK生成电子表格 . 我目前使用大约5种不同的单元格格式,我在样式表中定义 . 这工作正常,假设我正在创建一个全新的文档 .
样式表看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<x:styleSheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:fonts>
<x:font>
<x:sz val="11" />
</x:font>
<x:font>
<x:sz val="18" />
</x:font>
<x:font>
<x:i />
<x:sz val="11" />
</x:font>
</x:fonts>
<x:fills>
<x:fill>
<x:patternFill patternType="none" />
</x:fill>
<x:fill>
<x:patternFill patternType="gray125" />
</x:fill>
<x:fill>
<x:patternFill patternType="solid">
<x:fgColor rgb="C0C0C0" />
</x:patternFill>
</x:fill>
<x:fill>
<x:patternFill patternType="solid">
<x:fgColor rgb="DCDCDC" />
</x:patternFill>
</x:fill>
</x:fills>
<x:borders>
<x:border />
<x:border>
<x:left style="thin" />
<x:right style="thin" />
<x:top />
<x:bottom />
<x:diagonal />
</x:border>
</x:borders>
<x:cellXfs>
<x:xf />
<x:xf fontId="1" fillId="2" borderId="1">
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
<x:xf fontId="0" fillId="0" borderId="1">
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
<x:xf>
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
<x:xf fontId="2" fillId="0" borderId="1">
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
<x:xf fontId="1" fillId="3" borderId="1">
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
</x:cellXfs>
</x:styleSheet>
我想支持第二种情况,我的程序将新工作表添加到预先存在的电子表格中 .
这可能是:
-
由我的程序创建的电子表格
-
由我的程序创建的电子表格,但在Excel中进行了修改
-
由Excel创建的电子表格
在现有电子表格中创建样式的最佳策略是什么?
理想情况下,我想检测是否已存在所需的样式,如果是,则重用它们 . 仅根据其定义检测样式将是混乱的代码 . 如果我可以为我定义的xf元素分配一个唯一的名称,那将更加实用 .
我知道我可以在cellStyles节点中定义命名样式,它引用cellStyleXfs集合中的项目,如:
<x:cellStyleXfs>
<x:xf />
<x:xf fontId="1" fillId="2" borderId="1">
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
<x:xf fontId="0" fillId="0" borderId="1">
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
<x:xf>
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
<x:xf fontId="2" fillId="0" borderId="1">
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
<x:xf fontId="1" fillId="3" borderId="1">
<x:alignment horizontal="left" vertical="top" wrapText="1" />
</x:xf>
</x:cellStyleXfs>
<x:cellStyles>
<x:cellStyle name="Standard" xfId="0" />
<x:cellStyle name="ML_Header" xfId="1" />
<x:cellStyle name="ML_LanguageText" xfId="2" />
<x:cellStyle name="ML_DefaultLeftAligned" xfId="3" />
<x:cellStyle name="ML_CommentText" xfId="4" />
<x:cellStyle name="ML_SubHeader" xfId="5" />
</x:cellStyles>
但是,我无法弄清楚cellStyleXfs集合中的项与callXfs集合之间的关系 .
此外,Excel的行为类似于拥有cellStyles和cellStyleXfs节点 . 如果我在excel中编辑电子表格,则会更改定义并删除其中一些定义 .
目前,这看起来不像是一个实用的解决方案 .
有什么办法可以为cellXfs元素中的xf节点分配名称吗?这会让生活更轻松 .
另一种方法是每次生成工作表时定义新样式(以及字体和填充和边框) . 反复完成,这会使文件每次都变大 .
什么是最好的策略?
1 回答
我有一个当然不完美的策略,但这对我的目的来说足够好 .
我决定
用于表征我使用固定属性集的样式
定义一个函数,用于查找与这些属性匹配的样式
如果找不到,则创建一个新样式
作为最低要求,我希望该函数至少能够找到它自己生成的样式 .
如果我的应用程序导出到相同的excel文件100次,我不想生成相同的样式100次,使excel文件每次都大一点 .
我指定的属性集是不完整的 . 例如,我没有指定字体系列 . 如果有一个样式与我的所有属性匹配,但使用了不同的字体,我仍然会使用这种样式 . 这对我来说没问题,但在另一个应用程序中它可能是不可接受的 .
由于历史原因,我的代码是在VB中,但它可以很容易地移植到C# .
这是我的代码的略微缩减版本 . 有19种不同的样式,由CreateStyleSheet()函数初始化 . 如果样式表根本不存在,那么它会在检查各个样式之前创建它 .
搜索或创建样式的主要功能是FindCellFormat . 它的15个参数定义了它检查的一组或多个属性 .
对于8种样式,有一个辅助函数FindCellFormatForStatus,但这并不是特别相关 .