我所做的:使用Interop和ClosedXML混合填充和格式化一个Excel文件。
首先,通过Interop填充文件,然后保存,关闭,然后使用ClosedXML格式化单元格的ClosedXML。
不幸的是,这种格式会导致Excel将我的文件视为“损坏”,并需要修复它。这是有关的部分:
var workbook = new XLWorkbook(xlsPath);
var sheet = workbook.Worksheet("Error Log");
for (var rownum = 2; rownum <= 10000; rownum++)
{
var oldcell = sheet.Cell("C" + rownum);
var newcell = sheet.Cell("D" + rownum);
var oldtext = oldcell.GetFormattedString();
if(string.IsNullOrEmpty(oldtext.Trim()))
break;
XlHelper.ColorCellText(oldcell, "del", System.Drawing.Color.Red);
XlHelper.ColorCellText(newcell, "add", System.Drawing.Color.Green);
}
workbook.Save();染色方法:
public static void ColorCellText(IXLCell cel, string tagName, System.Drawing.Color col)
{
var rex = new Regex("\\<g\\sid\\=[\\sa-z0-9\\.\\:\\=\\\"]+?\\>");
var txt = cel.GetFormattedString();
var mc = rex.Matches(txt);
var xlcol = XLColor.FromColor(col);
foreach (Match m in mc)
{
txt = txt.Replace(m.Value, "");
txt = txt.Replace("</g>", "");
}
var startTag = string.Format("[{0}]", tagName);
var endTag = string.Format("[/{0}]", tagName);
var crt = cel.RichText;
crt.ClearText();
while (txt.Contains(startTag) || txt.Contains(endTag))
{
var pos1 = txt.IndexOf(startTag);
if (pos1 == -1)
pos1 = 0;
var pos2 = txt.IndexOf(endTag);
if (pos2 == -1)
pos2 = txt.Length - 1;
var txtLen = pos2 - pos1 - 5;
crt.AddText(txt.Substring(0, pos1));
crt.AddText(txt.Substring(pos1 + 5, txtLen)).SetFontColor(xlcol);
txt = txt.Substring(pos2 + 6);
}
if (!string.IsNullOrEmpty(txt))
crt.AddText(txt);
}文件myfile.xlsx中的错误 进行了以下修复:_x000d__x000a__x000d__x000a_ 修复的记录: 字符串属性/xl/sharedStrings.xml-部件(字符串)
我已经查过所有的线索了。在受影响的工作表中,在Productivity工具的比较视图中,一些块显示为插入已修复的文件,并在损坏的文件中删除,尽管似乎没有发生任何重大更改--只有一件事:该单元格的样式属性。这里有一个例子:
<x:c r="AA2" s="59">
<x:f>
(IFERROR(VLOOKUP(G2,Legende!$A$42:$B$45,2,FALSE),0))
</x:f>
</x:c>我检查了styles.xml的样式59,但没有。在修复的文件中,此样式已更改为14,在我的styles.xml中它被列为数字格式。
不幸的是,对这些无效的样式索引进行全局搜索/替换不能解决这个问题。看到这里发生的事情与腐败的索引、重命名的xmls、无效的命名范围等不同,我采取了一种不同的方法:根本不使用互操作,也许损坏首先是由Excel引起的,而着色只是最后一根稻草。
只使用ClosedXml:
哇。只是哇哦。这就更糟了。我注释掉了着色部分,因为没有它,Interop生成了一个可读的文件,没有错误,所以这也是我对ClosedXml的期望。
以下是我如何打开文件并使用ClosedXml对工作表进行寻址:
var wb= new XLWorkbook(xlsPath);
var errors = wb.Worksheet("Error Log");我是这样将值写入文件的:
errors.Cell(zeile, 1).SetValue(fname);热情是一个简单的整数计数器。
然后,我敢设置一个列的宽度:
errors.Column(2).Width = 50;
errors.Column(3).Width = 50;
errors.Column(4).Width = 50;以及以完全相同的方式在另一个工作表中设置一些值,然后用验证保存。
wb.Save(true);
wb.Dispose();瞧,验证会抛出错误:
属性'name‘应该具有唯一的值。它的当前值'Legende‘与其他值重复。 属性'sheetId‘应该具有唯一的值。它的当前值'4‘与其他值重复。
还有几个错误,比如属性'top‘具有无效的值'11.425781’。
Excel不能直接打开文件,必须修复它。我的工作表"Legende“现在是空的,第一页而不是第三页,我得到了第四页"Restored_Table1”,其中包含了我原来的"Legende“内容。
这文件到底怎么回事??
新尝试:从头开始重新创建LibreOffice.模板
我认为这个问题是完全误导人的。如果我使用LibreOffice新创建的文件,由于验证错误太多,验证会导致System.OutOfMemory异常。在Excel中打开需要修复,提供额外的工作表等等。
在LibreOffice中创建,然后在Excel中打开,保存,然后使用该文件作为模板的生成一个更好的结果,尽管还不完美。由于在创建新文件时,我将旧Excel文件中的部分复制到LO中,因此,我假设一些损坏的残存已被复制。
我无法摆脱这样的感觉,这毕竟是文件本身,与我如何编辑它无关!
明天就会发帖。
发布于 2016-12-13 11:57:49
好的。把这个塞进去。我用LibreOffice创建了一个全新的文件,确保根本不复制原始文件中的任何内容,而且我放弃了Interop,转而使用ClosedXml。
=> --这产生了一个损坏的文件,其中我的第一张纸被清除,其内容移到"Restored_Table1“。
在我通过打开/修复打开/修复Excel打开新模板并保存它之后,生成的未着色文件没有损坏。
=>着色它产生了“原始”的腐败,所有的纸张都完好无损。
ClosedXml似乎比Interop稍慢一些,但在这一点上,我不太在意。我想我们将不得不接受“腐败”的信息,并继续下去。
我讨厌xlsx。
https://stackoverflow.com/questions/40885615
复制相似问题