我使用OpenXML SDK在C#中生成了一个.xlsx电子表格,但无法弄清楚如何使单元格样式起作用 . 我一直在研究Excel生成的文件,并且无法弄清楚它是如何完成的 .
现在,我正在创建一个填充,创建一个指向填充的 CellStyleFormat
,创建一个指向 CellStyleFormat
索引的 CellFormat
,然后创建一个指向 CellFormat
的 CellStyle
.
这是我用来生成文档的代码:
Console.WriteLine("Creating document");
using (var spreadsheet = SpreadsheetDocument.Create("output.xlsx", SpreadsheetDocumentType.Workbook))
{
Console.WriteLine("Creating workbook");
spreadsheet.AddWorkbookPart();
spreadsheet.WorkbookPart.Workbook = new Workbook();
Console.WriteLine("Creating worksheet");
var wsPart = spreadsheet.WorkbookPart.AddNewPart<WorksheetPart>();
wsPart.Worksheet = new Worksheet();
var stylesPart = spreadsheet.WorkbookPart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = new Stylesheet();
stylesPart.Stylesheet.Fills = new Fills();
// create a solid red fill
var solidRed = new PatternFill() { PatternType = PatternValues.Solid };
solidRed.AppendChild(new BackgroundColor { Rgb = HexBinaryValue.FromString("FF00FF00") });
stylesPart.Stylesheet.Fills.AppendChild(new Fill { PatternFill = new PatternFill() { PatternType = PatternValues.None } });
stylesPart.Stylesheet.Fills.AppendChild(new Fill { PatternFill = solidRed });
stylesPart.Stylesheet.CellStyleFormats = new CellStyleFormats();
stylesPart.Stylesheet.CellStyleFormats.AppendChild(new CellFormat { FillId = 0, ApplyFill = false });
stylesPart.Stylesheet.CellStyleFormats.AppendChild(new CellFormat { FillId = 1, ApplyFill = true });
stylesPart.Stylesheet.CellFormats = new CellFormats();
stylesPart.Stylesheet.CellFormats.AppendChild(new CellFormat { FormatId = 0 });
stylesPart.Stylesheet.CellFormats.AppendChild(new CellFormat { FormatId = 1 });
stylesPart.Stylesheet.CellStyles = new CellStyles();
stylesPart.Stylesheet.CellStyles.AppendChild(new CellStyle { Name = "None", FormatId = 0 });
stylesPart.Stylesheet.CellStyles.AppendChild(new CellStyle { Name = "Solid Red", FormatId = 1 });
stylesPart.Stylesheet.Save();
Console.WriteLine("Creating sheet data");
var sheetData = wsPart.Worksheet.AppendChild(new SheetData());
Console.WriteLine("Adding rows / cells...");
var row = sheetData.AppendChild(new Row());
row.AppendChild(new Cell() { CellValue = new CellValue("This"), DataType = CellValues.String });
row.AppendChild(new Cell() { CellValue = new CellValue("is"), DataType = CellValues.String });
row.AppendChild(new Cell() { CellValue = new CellValue("a"), DataType = CellValues.String });
row.AppendChild(new Cell() { CellValue = new CellValue("test."), DataType = CellValues.String });
sheetData.AppendChild(new Row());
row = sheetData.AppendChild(new Row());
row.AppendChild(new Cell() { CellValue = new CellValue("Value:"), DataType = CellValues.String });
row.AppendChild(new Cell() { CellValue = new CellValue("123"), DataType = CellValues.Number });
row.AppendChild(new Cell() { CellValue = new CellValue("Formula:"), DataType = CellValues.String });
row.AppendChild(new Cell() { CellFormula = new CellFormula("B3"), StyleIndex = 1 }); //
Console.WriteLine("Saving worksheet");
wsPart.Worksheet.Save();
Console.WriteLine("Creating sheet list");
var sheets = spreadsheet.WorkbookPart.Workbook.AppendChild(new Sheets());
sheets.AppendChild(new Sheet() { Id = spreadsheet.WorkbookPart.GetIdOfPart(wsPart), SheetId = 1, Name = "Test" });
Console.WriteLine("Saving workbook");
spreadsheet.WorkbookPart.Workbook.Save();
Console.WriteLine("Done.");
}
这是生成的XML:
workbook.xml
<?xml version="1.0" encoding="utf-8"?>
<x:workbook xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:sheets>
<x:sheet name="Test" sheetId="1" r:id="Rbad86b8c80844a16" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" />
</x:sheets>
</x:workbook>
styles.xml
<?xml version="1.0" encoding="utf-8"?>
<x:styleSheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:fills>
<x:fill>
<x:patternFill patternType="none" />
</x:fill>
<x:fill>
<x:patternFill patternType="solid">
<x:bgColor rgb="FF00FF00" />
</x:patternFill>
</x:fill>
</x:fills>
<x:cellStyleXfs>
<x:xf fillId="0" applyFill="0" />
<x:xf fillId="1" applyFill="1" />
</x:cellStyleXfs>
<x:cellXfs>
<x:xf xfId="0" />
<x:xf xfId="1" />
</x:cellXfs>
<x:cellStyles>
<x:cellStyle name="None" xfId="0" />
<x:cellStyle name="Solid Red" xfId="1" />
</x:cellStyles>
</x:styleSheet>
worksheets/sheet.xml
<?xml version="1.0" encoding="utf-8"?>
<x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:sheetData>
<x:row>
<x:c t="str"><x:v>This</x:v></x:c>
<x:c t="str"><x:v>is</x:v></x:c>
<x:c t="str"><x:v>a</x:v></x:c>
<x:c t="str"><x:v>test.</x:v></x:c>
</x:row>
<x:row />
<x:row>
<x:c t="str"><x:v>Value:</x:v></x:c>
<x:c t="n"><x:v>123</x:v></x:c>
<x:c t="str"><x:v>Formula:</x:v></x:c>
<x:c s="1"><x:f>B3</x:f></x:c>
</x:row>
</x:sheetData>
</x:worksheet>
最后一行的最后一个单元格是我尝试添加样式的位置 .
当我通过OpenXML SDK Productivity Tool运行它时,这一切都正确验证,但是,当我尝试在Excel中打开文件时,我收到以下错误:
修复记录:来自/xl/styles.xml部分的格式(样式)
然后会显示电子表格,但不会应用填充 .
知道如何解决这个问题吗?
2 回答
是的,经过大量的实验,我成功地解决了这个问题 .
事实证明,excel保留了正常单元格的样式0和1以及"Gray125"模式填充 . 上面的大部分代码都可以删除,因为我们只需要一个
CellFormat
.工作代码:
一些忠告:
如果你想避免这种疯狂,请使用ClosedXML .
I cannot recommend ClosedXML highly enough if you're doing this kind of work. OpenXML API和格式非常繁琐,可以单独使用各种未记录的案例 . ClosedXML为您完成了大量的工作 . 他们也非常擅长快速修复错误 .
一个更通用的答案,我在测试后发现的所有这些,所以没有文档指出 .
在样式表中设置
CellFormats
集合后,Excel会对其进行更深入的验证 .CellFormats
不能为空,它必须至少有一个CellFormat
.添加
CellFormat
后,如果Fills
,Fonts
或Borders
集合为空,Excel将会发出警告 .首先
Font
用作整个工作簿的默认值,也用作Excel中的列/行 Headers .Excel将首先忽略
CellFormat
,因此只需添加一个空的 .如果您的格式需要
Border
或Fill
,Excel也会先忽略Border
和Fill
,因此在Borders
和Fills
中添加空的第一个孩子 .最后,从第二个
CellFormat
(s = "1"
)开始,你很高兴 .在Excel 2010中测试 .