zoukankan      html  css  js  c++  java
  • C#使用NPOI根据模板生成Word文件功能实现

    最近在做一个项目,需要根据模板生成一个销售合同的功能,百度了一下发现有几个插件可以使用

    1.使用Microsoft.Office.Interop.Word生成,这种方法需要本地安装了Office才可以,由于功能在客户电脑上使用,不能保证都安装了office,这种方法被pass

    2.使用Aspose.Words,这个方法不需要本地安装Office,有免费版本,但是我看了一下演示代码比较复杂,所以也没有考虑这种方法

    3.使用NPOI生成word,这种方法.NET也有现成的插件引用,可以通过NuGet安装包,所以我采用了这种方式

    由于网上有一些关于NPOI生成Word文件的方法,我也使用了网上提供的代码,我就讲一下使用中遇到的问题

    我采用了博客园一个博主的代码,引用地址:https://www.cnblogs.com/byron-123/p/12956621.html,在应用代码中我遇到了以下问题

    问题1:根据List数据生成表格,生成后word文件无法打开,提示内容有问题,研究了很久好现是以下代码生成的表格会无法打开,所以我改以一下代码

      原来的代码:

    /// <summary>
            /// 替换表格Key
            /// </summary>
            /// <param name="para"></param>
            /// <param name="model"></param>
            private static void ReplaceTableKey(XWPFTable table, IList list, String field)
            {
                List<XWPFParagraph> paras = new List<XWPFParagraph>();
                // 获取最后一行数据,最后一行设置值
                Int32 iLastRowIndex = 0;
                for (int iIndex = 0; iIndex < table.Rows.Count; iIndex++)
                {
                    if (iIndex == table.Rows.Count - 1)
                    {
                        iLastRowIndex = iIndex;
                        foreach (var cell in table.Rows[iIndex].GetTableCells())
                        {
                            foreach (var para in cell.Paragraphs)
                            {
                                paras.Add(para);
                            }
                        }
                    }
                }
                // 删除最后一行
                table.RemoveRow(iLastRowIndex);
    
                for (int iIndex = 0; iIndex < list.Count; iIndex++)
                {
                    dynamic data = list[iIndex];
                    Type t = data.GetType();
                    PropertyInfo[] pi = t.GetProperties();
                    // 表增加行
                    XWPFTableRow m_row = table.CreateRow();
                    CT_Row m_NewRow = new CT_Row();
                    String text = String.Empty;
                    Int32 jIndex = 0;
                    paras.ForEach(para =>
                    {
                        text = para.ParagraphText;
                        foreach (PropertyInfo p in pi)
                        {
                            if (text.Contains("$" + field + "." + p.Name + "$"))
                            {
                                m_row.GetCell(jIndex).SetText(p.GetValue(data, null).ToString());
                            }
                        }
                        jIndex++;
                    });
                    m_row = new XWPFTableRow(m_NewRow, table);
                    table.AddRow(m_row);
    
                }
            }

    修改后的代码:更换了原来的逻辑,原来根据模板表格的行复制生成新的行,改了之后是插入新的行,只是利用原来行的模板数据

     public static void TableInsertNewRows(XWPFTable table, IList<object> list, string field, string leftSplit = "$", string rightSplit = "$")
            {
                List<XWPFParagraph> paras = new List<XWPFParagraph>();
                // 获取最后一行数据,最后一行设置值
                if (table.Rows.Count >= 2)
                {
                    foreach (var cell in table.Rows[1].GetTableCells())
                    {
                        foreach (var para in cell.Paragraphs)
                        {
                            paras.Add(para);
                        }
                    }
                    //删除数据行
                    table.RemoveRow(1);
                }
    
    
    
                dynamic data = list[0];
                Type t = data.GetType();
                PropertyInfo[] pi = t.GetProperties();
                String text = String.Empty;
                for (int i = 0; i < list.Count; i++)
                {
                    XWPFTableRow m_Row = table.InsertNewTableRow(1 + i);//创建一行/并且在某个位置添加一行
                    foreach (var para in paras)
                    {
                        text = para.ParagraphText;
                        foreach (PropertyInfo p in pi)
                        {
                            if (text.Contains(leftSplit + field + "." + p.Name + rightSplit))
                            {
                                m_Row.AddNewTableCell().SetText(p.GetValue(data, null).ToString());
                                break;
                            }
                        }
                    }
                }
    
            }

      

    问题2:模板文件中包含图片导致生成的word文件也无法打开,提示也是内容有问题,修改方法,将图片通过代码插入word文件,这样产生的问题是,图片无法设置环绕模式

    代码下载:https://download.csdn.net/download/rxyhj/19804923

  • 相关阅读:
    BW中变量增强学习
    视频压制参数设置详细说明(转)
    swf文件格式解析(二)
    关于FP10.2的自定义鼠标功能
    swf文件格式解析(一)
    如何判断winform程序已安装过
    flashbuilder4.5 作为eclipse插件
    安装程序无法创建新的系统分区,也无法定位现有系统分区 (转载于百度文库)
    【转】VS2008建造打包法度将安装路径写入注册表
    【高清视频压制教程】使用MeGUI压制视频教程(以PSP视频为例)(转载)
  • 原文地址:https://www.cnblogs.com/ithome8/p/14925770.html
Copyright © 2011-2022 走看看