卍无名英雄卐 2024-09-23 00:36 采纳率: 25%
浏览 20
已结题

c#使用NPOI向word表格中添加字段导致word有概率警告不可识别

我在vs用c#写窗体程序用来做表格读取和word生成,用了NPOI和interop.word两个程序包,之前写了两个功能都能正常使用,包括了读取excel数据、生成word文字、合并多个word的过程。

今天编写新功能的时候引用了很多之前的代码,也进行了参数更改,原有函数可以完美运行,新增了一个插入图片的函数,也能正常使用。

但是文档合并时调用interop.word的insert函数显示无法打开先前生成的文件,尝试过多种解决方法均未解决。
1、创建类似格式的新模板文件,再用程序生成文件。结果word报错,忽略错误后所有字符均可正常显示。
2、注释部分插入段落的语句。结果word可以正常打开。(最后确认为一段插入随机字符的段落会引发报错,并且插入的数量越多越容易报错)
3、在之前插入随机字符的段落前新建一个字符串,把所有随机字符替换为该字符串并插入word中。结果word可以正常打开。
4、注释掉SetTableFont函数,最后生成的word同样异常。

这段随机字符生成代码在先前功能中使用过多次,均没有发生这个问题。

救命,研究了七八个小时了还在原地转圈

直接引发问题的程序段落:
table1、table2:上文定义的用于存储模板word中两个表格的变量
datetime:DateTime数组,存储一组随机生成的开始时间
dt:int数组,存储一组随机生成的持续时间

                for (int i = 1; i <= leadnum; i++)
                {
                    XWPFTable table;
                    XWPFTableRow row;
                    if (i <= 24)
                    {
                        table = table1;
                        row = table.GetRow(i + 5);
                    }
                    else
                    {
                        table = table2;
                        row = table.GetRow(i - 19);
                    }
                    row.GetCell(1).SetParagraph(SetTableFont(table, datetime[i - 1].ToString("H:mm"), ParagraphAlignment.CENTER, 12, "FF0000"));
                    row.GetCell(2).SetParagraph(SetTableFont(table, datetime[i - 1].AddMinutes(dt[i - 1]).ToString("H:mm"), ParagraphAlignment.CENTER, 12, "FF0000"));
                    row.GetCell(3).SetParagraph(SetTableFont(table, (gradeinfo.lead_len + 0.05 + (rand.Next() % 6) * 0.01).ToString("f2"), ParagraphAlignment.CENTER, 12, "FF0000"));
                    row.GetCell(4).SetParagraph(SetTableFont(table, (gradeinfo.lead_spc * 1000 - 30 + (rand.Next() % 7) * 10).ToString("f0"), ParagraphAlignment.CENTER, 12, "FF0000"));
                    row.GetCell(5).SetParagraph(SetTableFont(table, (rand.Next() % 3).ToString("f0"), ParagraphAlignment.CENTER, 12, "FF0000"));
                    if (gradeinfo.grade == "V")
                    {
                        row.GetCell(6).SetParagraph(SetTableFont(table, (gradeinfo.lead_grt_pre + (rand.Next() % 11) * 0.1).ToString("f1"), ParagraphAlignment.CENTER, 12, "FF0000"));
                        row.GetCell(7).SetParagraph(SetTableFont(table, (gradeinfo.lead_grt_vol + (rand.Next() % 21)).ToString("f0"), ParagraphAlignment.CENTER, 12, "FF0000"));
                    }
                    GC.Collect();
                }
                for (int i = 0; i < 8; i++)
                {
                    table1.GetRow(32).GetCell(i).SetBorderRight(XWPFTable.XWPFBorderType.SINGLE, 8, 0, "000000");
                    table1.GetRow(32).GetGetCell(i + 1).SetBorderLeft(XWPFTable.XWPFBorderType.SINGLE, 8, 0, "000000");
                    table2.GetRow(32).GetCell(i).SetBorderRight(XWPFTable.XWPFBorderType.SINGLE, 8, 0, "000000");
                    table2.GetRow(32).GetCell(i + 1).SetBorderLeft(XWPFTable.XWPFBorderType.SINGLE, 8, 0, "000000");

SetTableFront函数:

        public XWPFParagraph SetTableFont(XWPFTable table, string str,ParagraphAlignment align,int size = 9,string color = "000000")
        {
            CT_P para = new CT_P();
            para.AddNewPPr().AddNewTextAlignment();
            XWPFParagraph paragraph = new XWPFParagraph(para, table.Body);
            paragraph.Alignment = align;
            string[] strings = str.Split('\n');
            for(int i = 0; i < strings.Length; i++)
            {
                XWPFRun run = paragraph.CreateRun();
                if (i!=0)
                {
                    run.AddBreak(BreakType.TEXTWRAPPING);
                }
                run.SetText(strings[i]);
                run.FontSize = size;
                run.SetColor(color);
                run.SetFontFamily("宋体", FontCharRange.None);
            }
            return paragraph;
        }

  • 写回答

10条回答 默认 最新

  • 阿里嘎多学长 2024-09-23 00:36
    关注

    以下内容由AIGC及阿里嘎多学长共同生成、有用望采纳:


    从您提供的代码和描述中,问题似乎出现在使用NPOI库向Word文档中的表格添加字段时。您提到,当尝试合并文档时,使用interop.word的insert函数无法打开先前生成的文件。您也提到,注释掉插入段落的代码后,Word可以正常打开文件,这表明问题可能与段落的插入有关。

    问题分析

    1. 随机字符生成:您提到插入随机字符的段落会引发报错,这可能是因为某些特殊字符或字符组合不被Word识别,或者在处理时出现了编码问题。
    2. 段落插入:在您的代码中,您使用了SetTableFont方法来设置段落的字体和样式。如果这个方法在处理某些字符时存在问题,可能会导致Word无法识别。
    3. 文档合并:在合并文档时,可能存在文件锁定或格式不兼容的问题,这需要进一步检查。

    解决方案

    1. 检查特殊字符:确保插入的随机字符不包含Word无法识别的特殊字符。您可以在插入前对字符进行过滤。
    2. 简化段落插入:尝试使用更简单的方法插入段落,看是否还会出现同样的问题。
    3. 文档合并策略:检查合并文档时的代码,确保在合并前文件没有被锁定,且格式兼容。

    示例代码

    下面是一个简化的示例,展示如何安全地插入段落并合并文档:

    public XWPFParagraph SetTableFont(XWPFTable table, string str, ParagraphAlignment align, int size = 9, string color = "000000")
    {
        XWPFParagraph paragraph = table.CreateParagraph();
        paragraph.Alignment = align;
        XWPFRun run = paragraph.CreateRun();
        run.SetText(str);
        run.FontSize = size;
        run.SetColor(color);
        run.SetFontFamily("宋体");
    
        return paragraph;
    }
    
    public void InsertData(XWPFTable table, DateTime[] datetime, int[] dt, int leadnum)
    {
        for (int i = 1; i <= leadnum; i++)
        {
            XWPFTableRow row;
            if (i <= 24)
            {
                row = table.GetRow(i + 5);
            }
            else
            {
                row = table.GetRow(i - 19);
            }
            row.GetCell(1).SetParagraph(SetTableFont(table, datetime[i - 1].ToString("H:mm"), ParagraphAlignment.CENTER, 12, "FF0000"));
            row.GetCell(2).SetParagraph(SetTableFont(table, datetime[i - 1].AddMinutes(dt[i - 1]).ToString("H:mm"), ParagraphAlignment.CENTER, 12, "FF0000"));
            // 省略其他字段的插入
        }
    }
    
    public void MergeDocuments(List<XWPFDocument> docs)
    {
        XWPFDocument mergedDoc = new XWPFDocument();
        foreach (var doc in docs)
        {
            foreach (var paragraph in doc.Paragraphs)
            {
                mergedDoc.ImportParagraph(paragraph);
            }
        }
        // 保存合并后的文档
        mergedDoc.Write(new FileStream("merged.docx", FileMode.Create));
    }
    

    运行环境

    • .NET Framework:确保您的项目使用的是兼容的.NET Framework版本。
    • NPOI:使用最新版本的NPOI库,以确保所有功能都是最新的。

    测试

    • 单元测试:对每个功能进行单元测试,确保在合并文档之前每个部分都能正常工作。
    • 异常处理:在代码中添加异常处理逻辑,以便在出现问题时能够捕获并处理。

    通过这些步骤,您应该能够解决Word文档处理中遇到的问题。如果问题仍然存在,可能需要进一步检查Word的兼容性设置或考虑使用其他库。


    AIGC生成:


    NPOI向Word表格中添加字段导致Word有概率警告不可识别

    你遇到的问题是使用NPOI向Word表格中添加字段导致Word有概率警告不可识别,这可能是由于Word中的表格格式或字段类型不支持NPOI生成的内容导致的。下面列举一些可能的解决方法:

    1. 检查Word表格的格式:确保Word表格的格式正确,包括表格的边框、字体、对齐方式等。如果Word表格的格式不正确,可能会导致NPOI生成的内容不可识别。
    2. 使用NPOI的HSSFFormula:如果你需要在Word表格中添加公式,可以使用NPOI的HSSFFormula类来实现。这个类可以将公式转换为Word可以识别的格式。
    3. 使用NPOI的HSSFCellStyle:如果你需要在Word表格中添加样式,可以使用NPOI的HSSFCellStyle类来实现。这个类可以将样式转换为Word可以识别的格式。
    4. 检查NPOI版本:确保你使用的NPOI版本是最新的。如果你使用的NPOI版本较低,可能会导致一些问题。
    5. 使用其他Word库:如果你遇到的问题仍然无法解决,可以尝试使用其他Word库,例如Aspose.Words或EPPlus。
    6. 检查Word表格的编码:确保Word表格的编码是UTF-8,如果不是,可以尝试将编码改为UTF-8。
    7. 使用NPOI的HSSFWorkbook:如果你需要在Word表格中添加大量数据,可以使用NPOI的HSSFWorkbook类来实现。这个类可以将数据转换为Word可以识别的格式。

    这些方法可能可以帮助你解决问题,如果你仍然遇到问题,可以提供更多的信息和代码,以便我更好地帮助你解决问题。


    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月23日
  • 修改了问题 9月23日
  • 创建了问题 9月23日

悬赏问题

  • ¥15 依据报错在原代吗格式的基础上解决问题
  • ¥15 在虚拟机中安装flash code
  • ¥15 单片机stm32f10x编写光敏电阻调节3.3伏大功率灯亮度(光强越大灯越暗,白天正常光强灯不亮,使用ADC,PWM等模块)望各位找一下错误或者提供一个可实现功能的代码
  • ¥20 verilog状态机方法流水灯
  • ¥15 pandas代码实现不了意图
  • ¥15 GD32H7 从存储器到外设SPI传输数据无法重复启用DMA
  • ¥25 LT码在高斯信道下的误码率仿真
  • ¥45 渲染完成之后将物体的材质贴图改变,自动化进行这个操作
  • ¥15 yolov5目标检测并显示目标出现的时间或视频帧
  • ¥15 电视版的优酷可以设置电影连续播放吗?