dotnetcore/NPOI

[Word/.docx] How to clear a Cell in Word

CodingOctocat opened this issue · 1 comments

This is my code:

public static void RemoveAllParagraphs(XWPFTableCell cell, Predicate<string> match = default)
{
    var tempPs = cell.Paragraphs.ToList();

    int count = cell.Paragraphs.Count;

    for (int i = 0; i < count; i++)
    {
        cell.RemoveParagraph(0);
    }

    match ??= _ => true;

    var ps = tempPs.Where(x => !match(x.ParagraphText));

    foreach (var item in ps)
    {
        // cell.AddParagraph(item) 👀 If i use this code, the document will be corrupted.
        AppendCellParagraph(cell, item.ParagraphText, item.Runs[0].GetColor(), item.FillBackgroundColor);
    }

    if (cell.Paragraphs.Count == 0)
    {
        AppendCellParagraph(cell, "");
    }
}

public static XWPFParagraph AppendCellParagraph(XWPFTableCell cell, string text, string fg = "auto", string bg = "auto")
{
    var p = cell.AddParagraph();
    XWPFRun run = p.CreateRun();
    run.SetText(text);
    run.FontFamily = "宋体";
    run.FontSize = 9;
    run.SetColor(fg);
    p.AddRun(run);
    p.FillBackgroundColor = bg;
    p.Alignment = ParagraphAlignment.CENTER;
    p.VerticalAlignment = TextAlignment.CENTER;

    return p;
}

public static void RemoveBlankParagraphs(XWPFTableCell cell)
{
    RemoveAllParagraphs(cell, x => String.IsNullOrWhiteSpace(x));
}

This code can satisfy me, but obviously it's not perfect.
And I don't understand why the commented code above corrupts the document.

I tried it many times to find a solution that didn't corrupt the document and worked as expected:

public static void RemoveAllParagraphs(XWPFTableCell cell, Predicate<string> match = default)
{
    match ??= _ => true;

    var removes = new List<int>();

    for (int i = cell.Paragraphs.Count - 1; i >= 0; i--)
    {
        if (match(cell.Paragraphs[i].ParagraphText))
        {
            removes.Add(i);
        }
    }

    int x = 0;

    if (removes.Count == cell.Paragraphs.Count)
    {
        x = 1;
    }

    for (int i = 0; i < removes.Count - x; i++)
    {
        cell.RemoveParagraph(removes[i]);
    }

    string p0Text = cell.Paragraphs[0].ParagraphText;

    if (cell.Paragraphs.Count == 1 && p0Text != "" && match(p0Text))
    {
        cell.Paragraphs[0].ReplaceText(p0Text, "");
    }
}