C# Excel中的彩色文本部分>;255个字符

C# Excel中的彩色文本部分>;255个字符,c#,excel,openxml,excel-interop,C#,Excel,Openxml,Excel Interop,我已经为第三方软件编写了一个插件,它将修改后的文本提取到Excel工作表中,然后在Excel中为修改后的部分着色。 只要每个文本段(=单元格内容)不超过255个字符,此操作就有效。唉,这种情况有时也会发生 为了在Excel中识别更改的部分,我用resp将它们包围起来删除和添加文本的标记。然后我给这些部分上色(并移除周围的标签),如下所示: while (((string)cell1.Text).Contains("<del>")) { try { va

我已经为第三方软件编写了一个插件,它将修改后的文本提取到Excel工作表中,然后在Excel中为修改后的部分着色。 只要每个文本段(=单元格内容)不超过255个字符,此操作就有效。唉,这种情况有时也会发生

为了在Excel中识别更改的部分,我用
resp将它们包围起来<代码>删除和添加文本的标记。然后我给这些部分上色(并移除周围的标签),如下所示:

while (((string)cell1.Text).Contains("<del>"))
{
    try
    {
        var pos = ((string) cell1.Text).IndexOf("<del>") + 1;
        var pos2 = ((string) cell1.Text).IndexOf("</del>") + 1;
        var txt = cell1.Characters[pos, (pos2-pos) + 9].Text;

        txt = txt.Replace("<del>", "").Replace("</del>", "");
        cell1.Characters[pos, (pos2-pos) + 9].Text = txt;
        cell1.Characters[pos, txt.Length-3].Font.Color = -16776961;
    }
    catch
    {
            break;
    }
}
while(((字符串)cell1.Text).Contains(“”)
{
尝试
{
var pos=((字符串)cell1.Text).IndexOf(“”+1;
var pos2=((字符串)cell1.Text).IndexOf(“”+1;
var txt=cell1.字符[pos,(pos2 pos)+9].文本;
txt=txt.Replace(“,”).Replace(“,”);
单元格1.字符[pos,(pos2 pos)+9].Text=txt;
cell1.字符[pos,txt.Length-3].Font.Color=-16776961;
}
抓住
{
打破
}
}
我之所以使用互操作,是因为我发现它更容易使用,也因为我找不到任何关于如何使用OpenXML实现这一点的好例子。然而,我知道Excel在单元格文本方面有其局限性,所以我愿意接受建议

是否有一种方法可以使用互操作为包含超过255个字符的单元格中的单个单词着色

如果一切都失败了,我可能需要创建一个带有表格的Word文档,在那里进行格式化,然后复制/粘贴到Excel(Yuk)。请帮我避免这种丑陋


附言:是的,修订摘要需要基于Excel。

好的,我现在用OpenXML解决了它。 如果单元格包含要着色的文本,我将创建一个到该位置的文本运行,第二个彩色运行包含受影响的文本,第三个返回默认运行包含其余文本

var xlsx = SpreadsheetDocument.Open(xlsPath, true);
var contents = xlsx.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
foreach (SharedStringItem si in contents.SharedStringTable.Elements<SharedStringItem>())
{
    if (si.Text != null)
    {
        XlHelper.ColorCellText(si, "del", new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = "FFFF0000" });
        XlHelper.ColorCellText(si, "add", new DocumentFormat.OpenXml.Spreadsheet.Color { Rgb = "0000BF00" });
    }
}
var xlsx=SpreadsheetDocument.Open(xlsPath,true);
var contents=xlsx.WorkbookPart.GetPartsOfType().First();
foreach(contents.SharedStringTable.Elements()中的SharedStringItem si)
{
如果(si.Text!=null)
{
XlHelper.ColorCellText(si,“del”,new DocumentFormat.OpenXml.Spreadsheet.Color{Rgb=“FFFF0000”});
XlHelper.ColorCellText(si,“添加”,new DocumentFormat.OpenXml.Spreadsheet.Color{Rgb=“0000BF00”});
}
}
以及我的XlHelper.ColorCellText方法:

public static void ColorCellText(SharedStringItem si, string TagName, DocumentFormat.OpenXml.Spreadsheet.Color col)
{
    var newText = si.InnerText;
    var startTag = string.Format("<{0}>", TagName);
    var endTag = string.Format("</{0}>", TagName);
    if (newText.Contains(startTag))
    {
        si.Text.Remove();
        var lastpos = 0;
        while (newText.Contains(startTag))
        {
            try
            {
                var pos1 = newText.IndexOf(startTag);
                var pos2 = newText.IndexOf(endTag);
                var txtLen = pos2 - pos1 - 5;
                var it = string.Concat(newText.Substring(0, pos1), newText.Substring(pos1 + 5, txtLen),
                    newText.Substring(pos2 + 6));

                var run = new Run();
                var txt = new Text
                {
                    Text = it.Substring(0, pos1),
                    Space = SpaceProcessingModeValues.Preserve
                };
                run.Append(txt);
                si.Append(run);

                run = new Run();
                txt = new Text
                {
                    Text = it.Substring(pos1, txtLen),
                    Space = SpaceProcessingModeValues.Preserve
                };

                var rp = new RunProperties();

                rp.Append(col.CloneNode(true));
                run.RunProperties = rp;
                run.Append(txt.CloneNode(true));
                si.Append(run.CloneNode(true));

                newText = newText.Substring(pos2 + 6);
            }
            catch(Exception ex)
            {
                using (var sw = new StreamWriter(logFile, true))
                {
                    sw.WriteLine("Error: {0}\r\n{1}", ex.Message, newText);
                }
                break;
            }
        }
        if (newText.Length>=0)
        {
            var lastrun = new Run();
            var lasttxt = new Text
            {
                Text = newText,
                Space = SpaceProcessingModeValues.Preserve
            };
            lastrun.Append(lasttxt);
            si.Append(lastrun);
        }
    }
}
public static void ColorCellText(SharedStringItem si,字符串标记名,DocumentFormat.OpenXml.Spreadsheet.Color col)
{
var newText=si.InnerText;
var startTag=string.Format(“,标记名);
var endTag=string.Format(“,标记名);
if(newText.Contains(startTag))
{
si.Text.Remove();
var-lastpos=0;
while(newText.Contains(startTag))
{
尝试
{
var pos1=newText.IndexOf(startTag);
var pos2=newText.IndexOf(endTag);
var txtLen=pos2-pos1-5;
var it=string.Concat(newText.Substring(0,pos1),newText.Substring(pos1+5,txtLen),
newText.Substring(pos2+6));
var run=new run();
var txt=新文本
{
Text=it.Substring(0,pos1),
Space=SpaceProcessingModeValues.Preserve
};
run.Append(txt);
附加(运行);
运行=新运行();
txt=新文本
{
Text=it.Substring(pos1,txtLen),
Space=SpaceProcessingModeValues.Preserve
};
var rp=新的运行属性();
rp.Append(col.CloneNode(true));
run.RunProperties=rp;
Append(txt.CloneNode(true));
si.Append(run.CloneNode(true));
newText=newText.Substring(pos2+6);
}
捕获(例外情况除外)
{
使用(var sw=新StreamWriter(日志文件,true))
{
sw.WriteLine(“错误:{0}\r\n{1}”,例如Message,newText);
}
打破
}
}
如果(新文本长度>=0)
{
var lastrun=new Run();
var lasttxt=新文本
{
Text=newText,
Space=SpaceProcessingModeValues.Preserve
};
追加(lasttxt);
si.Append(lastrun);
}
}
}
Space=SpaceProcessingModeValues.Preserve部分在这里非常重要,否则它会将所有三个部分粘合在一起,并消除它们之间的空格


我想我会研究一下这个ePlus,因为它的“In-cell Richtext”功能听起来很有希望。

尝试使用cell.Value而不是cell.Text。至少在EPPlus中,Text是为用户显示的值,value是单元格的内容。因此,如果列宽小于内容,则Text属性的值与value属性的值不同。No go。字符没有值属性。@Magnetron抱歉,有点厚。当然我可以使用
cell.Value
。不过没什么区别。对于大于255的单元格仍然没有结果。OpenXML文档还不错,它的级别很低,您必须了解Excel的模型-单元格有样式。就像您可以在使用Excel时应用样式一样,您也可以使用SDK应用样式。您不需要实际修改文本。像EPPlus这样的高级库使这变得更容易,并且包含样式示例