干部任免管理系统(五)开源了一个c#开发的任免审批表转word的程序

avatar
作者
猴君
阅读量:0

前言:

        好久没有写博文了,最近有几位csdn的网友想找过来借鉴开发的管理系统,因为工作调整我已经不在公司管理干部了,整套系统当时本身就是为了方便自己工作捣鼓的,现在也没人用了。牵涉到打架java运行环境,数据库,整合企业微信登录等等,要用起来也不方便,所以干脆就重新把最核心的转换审批表到实体类,然后再转换为word,以及提取简历功能用c#写了winform程序了。

程序开源地址:

干部任免审批报转换为word: 将干部任免审批表批量转换为word格式

首先声明本人不是专业的程序员,代码是比较烂我自己也知道,纯属给大家提供一个解决问题的思路。

程序实现的主要代码:

       一、Lrmx文件解析:

        本质上中组部任免审批表的lrmx文件就是一个xml格式文档,只是后缀为lrmx格式,核心思想就是解析xml文件,让文件中的内容与我们自己所定义的类对应。

        1. 用到的依赖包:

        1.1 Nlog 及 Nlog.from  日志记录用
        1.2  NPOI 用于操作word和excel的。用这个包最大的好处就是你不需要去考虑客户端是否有安装office。
        1.3  System.Xml.XDocument 和   System.Xml.ReaderWriter   xml的解析工具了。

        2.  定义的几个核心实体类

        2.1 最核心的GanBu类
    public  class GanBu     {       public   String XingMing;   //姓名  1,0,0   1,0,1         public String XingBie;  //性别  1,0,2   1,0,3         public String ChuShengNianYue;  //出生年月  YYYYMM格式    1,0,4  1,0,5         public String MinZu;  //民族     1,1,0   1,1,1         public String JiGuan;   //籍贯  1,1,2     1,1,3         public String ChuShengDi;// 出生地  1,1,4  1,1,5         public String RuDangShiJian;// 入党时间   1,2,0         public String CanJiaGongZuoShiJian;//参加工作时间  1,2,2         public String JianKangZhuangKuang;//健康状况  1,2,4         public String ZhuanYeJiShuZhiWu;//专业技术职务  1,3,0         public String ShuXiZhuanYeYouHeZhuanChang;//熟悉专业有何专长   1,3,2         public String QuanRiZhiJiaoYu_XueLi;//全日制教育学历       1,4,2         public String QuanRiZhiJiaoYu_XueWei;//全日制教育学位 1,4,2         public String QuanRiZhiJiaoYu_XueLi_BiYeYuanXiaoXi;//全日制毕业学校   1,4,4         public String QuanRiZhiJiaoYu_XueWei_BiYeYuanXiaoXi;//全日制毕业院校专业     1,5,4         public String ZaiZhiJiaoYu_XueLi;//在职教育学历   1,6,2         public String ZaiZhiJiaoYu_XueWei;//在职教育学位  1,6,2         public String ZaiZhiJiaoYu_XueLi_BiYeYuanXiaoXi;//在职教育毕业院校    1,6,4         public String ZaiZhiJiaoYu_XueWei_BiYeYuanXiaoXi;//在职教育毕业院校专业  1,7,4         public String XianRenZhiWu;//现任职务     1,8,0         public String NiRenZhiWu;//拟任职务    1,9,0         public String NiMianZhiWu;//拟免职务   1,10,0         public List<JianLi> JianLi;  //简历   1,11,0         public String JiangChengQingKuang;//奖惩情况    2,0,0         public String NianDuKaoHeJieGuo;//年度考核结果    2,1,0         public String RenMianLiYou;//任免理由   2,2,0         public   List<JiaTingChengYuan> JiaTingChengYuan;//家庭成员   2,4,1  称谓    2   姓名      3  年龄  4  政治面貌  5  工作单位及职务         public String ChengBaoDanWei;//承报单位         public String JiSuanNianLingShiJian;//计算年龄时间         public String TianBiaoShiJian;//填报时间         public String TianBiaoRen;//填报人         public String ShenFenZheng;//身份证号码         public String ZhaoPian;//  照片         public String Version;//版本         public int NianLing; //年龄      }
        2.2  JianLi 类
   public  class JianLi    {        public String KaiShiNianYue;        public String JieSuNianYue;        public String JingLi;  //经历    }
        2.3  JiaTingChengYuan 类
   public  class JiaTingChengYuan     {         public String ChengWei;//称谓         public String XingMing;//姓名         public String ChuShengRiQi;//出生日期  YYYYMM         public String ZhengZhiMianMao;//政治面貌         public String GongZuoDanWeiJiZhiWu;//工作单位及职务         public int NianLing; //年龄     }

        3  解析lrmx文件过程

        代码就是读取xml文件,将对应的内容解析赋值给GanBu类

        3.1  完整转换为类的代码
 private GanBu LrmxToClass(string filename) {      GanBu ganBu = new GanBu();      Type type = ganBu.GetType();      try {           XmlDocument xmlDoc = new XmlDocument();          xmlDoc.Load(filename);          XmlNodeList nl = xmlDoc.DocumentElement.ChildNodes;          foreach (XmlNode node in nl)          {              //Debug.WriteLine(node.Name);              if (node.Name != "JianLi" && node.Name != "JiaTingChengYuan")              {                  FieldInfo fieldInfo = type.GetField(node.Name);                  fieldInfo.SetValue(ganBu, node.InnerText);               }               if (node.Name == "JianLi")              {                  List<JianLi> jianLiList = new List<JianLi>();                  string jianli = node.InnerText;                  int rowNums = 0;                  string[] JianLiArrayTmp = jianli.Split('\n');                  List<String> JianLiArray = new List<string>();                  foreach (string s in JianLiArrayTmp)                  {                      if (s.Replace("\n", "").Replace("\r","").Trim() != "")                      {                          JianLiArray.Add(s.Replace("\r",""));                      }                   }                  foreach (string line in JianLiArray)                  {                      if (line.Trim() != "")                      {                          if (!Tools.isStartWithNumber(line.Trim()))                          {                              jianLiList[rowNums - 1].JingLi = jianLiList[rowNums - 1].JingLi + " " + line.Trim();                                                       }                          else                          {                              JianLi jl = new JianLi();                              String[] partArray = Regex.Split(line, "  ");                              int tmpNum = 0;                              String jingli = "";                              foreach (string s in partArray)                              {                                  if (tmpNum == 0)                                  {                                      //第一列分割的用来做时间拆分                                      string[] a = Regex.Split(s, "--|——");                                      if (a.Length == 1)                                      {                                          a = Regex.Split(s, "-|—");                                      }                                      jl.KaiShiNianYue = a[0].Trim().Replace(" ","");                                      if (a.Length == 1)                                      {                                          jl.JieSuNianYue = "";                                      }                                      else                                      {                                          jl.JieSuNianYue += a[1].Trim().Replace(" ", "");                                       }                                      tmpNum++;                                  }                                  else                                  {                                      jingli += s.Trim();                                  }                               }                              jl.JingLi = jingli;                               jianLiList.Add(jl);                              rowNums++;                           }                      }                  }                    ganBu.JianLi = jianLiList;              }               if (node.Name == "JiaTingChengYuan")              {                  XmlNodeList node2list = node.ChildNodes;                  List<JiaTingChengYuan> jtcyList = new List<JiaTingChengYuan>();                  foreach (XmlNode node2 in node2list)                  {                      JiaTingChengYuan jtcy = new JiaTingChengYuan();                      XmlNodeList node3List = node2.ChildNodes;                      Type t2 = jtcy.GetType();                      foreach (XmlNode node3 in node3List)                      {                          FieldInfo fi = t2.GetField(node3.Name);                          fi.SetValue(jtcy, node3.InnerText.Trim());                      }                      jtcy.ChuShengRiQi = jtcy.ChuShengRiQi.Trim().Replace("\n", "").Replace("-", "");                      if (jtcy.ChuShengRiQi.Length == 6 || jtcy.ChuShengRiQi.Length == 8)                      {                           jtcy.NianLing = Tools.JiSuanNianLing(jtcy.ChuShengRiQi, Tools.NullToEmpty(ganBu.JiSuanNianLingShiJian), Tools.NullToEmpty(ganBu.TianBiaoShiJian));                      }                       jtcyList.Add(jtcy);                    }                  ganBu.JiaTingChengYuan = jtcyList;               }           }           //20240718 增加身份证提取出生日期          if (ganBu.ChuShengNianYue.Length == 6 || ganBu.ChuShengNianYue.Length == 8)          {              ganBu.NianLing = Tools.JiSuanNianLing(ganBu.ChuShengNianYue, Tools.NullToEmpty(ganBu.JiSuanNianLingShiJian), Tools.NullToEmpty(ganBu.TianBiaoShiJian));          }          else          {              if (!string.IsNullOrEmpty(ganBu.ShenFenZheng))              {                  ganBu.ChuShengNianYue = Tools.GetDate(ganBu.ShenFenZheng);                  ganBu.NianLing = Tools.JiSuanNianLing(ganBu.ChuShengNianYue, Tools.NullToEmpty(ganBu.JiSuanNianLingShiJian), Tools.NullToEmpty(ganBu.TianBiaoShiJian));              }           }            logger.Info(filename + "转换为类成功!");           return ganBu;            }catch(Exception ex)      {          logger.Error(ex.ToString());          logger.Error(filename + "转换为类失败!");          return ganBu;      }   } 
        3.2 转换过程中一些要点:        

        3.2.1  对于如何处理简历我的实现思路如下: 因为一条简历有可能会分行的,首先把简历的内容按行存到数组中,如果这行的内容不是数字开头(因为一条简历都是以年份开始的)那么这行就不是一条新的简历,而是一条简历分行了。如果再严格点可以取前四位是否为数字。

        3.2.2 对于干部年龄的计算,如果有填写计算年龄时间那么就用该字段取,如果没有取填表时间,如果都没有取当前时间。如果没有填写出生日期,那么看是否有填写身份证号码。

二、 转换为word过程:     

       转换为word的过程采用的是按照模板来进行内容填充,本来想采用占位符替换的方式,发现有些问题,后来决定还是老老实实通过代码来实现。  审批表核心部分内容实际是一个大大表格,那么就可以按照excel单元格填充的思路来做处理了。

        1.  完整代码

  try   {       GanBu ganBu = LrmxToClass(filename);                         string[]  tmpArr = filename.Split('\\');       string newFileName = tmpArr[tmpArr.Length - 1];       string filePath = Path.GetDirectoryName(filename);       String targetFilePath = ".\\docx\\"  + filePath.Substring(3, filePath.Length - 3) + "\\" +  newFileName.Substring(0,  newFileName.Length -5) + "-任免审批表.docx";        if (File.Exists(targetFilePath))       {           File.Delete(targetFilePath);       }        XWPFDocument docx;       using (FileStream stream = File.OpenRead(".\\spbmb.docx"))       {            docx = new XWPFDocument(stream);       }       foreach (XWPFParagraph ph in docx.Paragraphs)       {           foreach (XWPFRun r in ph.Runs)           {               if (r.Text == "填表人:")               {                   r.SetText("填表人:" + ganBu.TianBiaoRen);                }           }       }         if (!string.IsNullOrEmpty(ganBu.ZhaoPian.Replace("\r", "").Replace("\n", "")))       {           XWPFTableCell imageCell = docx.Tables[1].Rows[0].GetTableCells()[6];           XWPFParagraph pg = imageCell.Paragraphs[0];           XWPFRun run = pg.CreateRun();           byte[] b = Convert.FromBase64String(ganBu.ZhaoPian);           InputStream sbs = new ByteArrayInputStream(b);           run.AddPicture(new ByteArrayInputStream(b), (int)NPOI.SS.UserModel.PictureType.JPEG, "", 363 * 3600, 490 * 3600);       }         Boolean ifFirst = true;       int num = 0;       foreach (XWPFTable table in docx.Tables)       {           for (int i = 0; i < table.Rows.Count; i++)           {               for (int j = 0; j < table.Rows[i].GetTableCells().Count; j++)               {                   switch (table.Rows[i].GetTableCells()[j].GetText().Trim().Replace(" ", "").Replace("\r\n",""))                   {                       case "姓名":                           if (num == 1)                           {                               table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.XingMing);                           }                           break;                       case "性别":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.XingBie);                           break;                       case "出生年月(岁)":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.ChuShengNianYue.Substring(0, 4) + "." + ganBu.ChuShengNianYue.Substring(4, 2) + "(" + ganBu.NianLing + "岁)");                           break;                       case "民族":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.MinZu);                           break;                       case "籍贯":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.JiGuan);                           break;                       case "出生地":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.ChuShengDi);                           break;                       case "入党时间":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.RuDangShiJian);                           break;                       case "参加工作时间":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.CanJiaGongZuoShiJian);                           break;                       case "健康状况":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.JianKangZhuangKuang);                           break;                       case "专业技术职务":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.ZhuanYeJiShuZhiWu);                           break;                       case "熟悉专业有何专长":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.ShuXiZhuanYeYouHeZhuanChang);                           break;                       case "全日制教育":                           XWPFParagraph pg = table.Rows[i].GetTableCells()[j + 1].Paragraphs[0];                           XWPFRun run = pg.CreateRun();                           run.SetText(ganBu.QuanRiZhiJiaoYu_XueLi);                           run.AddBreak();                           run.SetText(ganBu.QuanRiZhiJiaoYu_XueWei);                           break;                       case "毕业院校系及专业":                           if (ifFirst)                           {                               XWPFParagraph pg2 = table.Rows[i].GetTableCells()[j + 1].Paragraphs[0];                               XWPFRun run2 = pg2.CreateRun();                               run2.SetText(ganBu.QuanRiZhiJiaoYu_XueLi_BiYeYuanXiaoXi);                               run2.AddBreak();                               run2.SetText(ganBu.QuanRiZhiJiaoYu_XueWei_BiYeYuanXiaoXi);                               ifFirst = false;                           }                           else                           {                               XWPFParagraph pg3 = table.Rows[i].GetTableCells()[j + 1].Paragraphs[0];                               XWPFRun run3 = pg3.CreateRun();                               run3.SetText(ganBu.ZaiZhiJiaoYu_XueLi_BiYeYuanXiaoXi);                               run3.AddBreak();                               run3.SetText(ganBu.ZaiZhiJiaoYu_XueWei_BiYeYuanXiaoXi);                               ifFirst = true;                           }                           break;                       case "在职教育":                           XWPFParagraph pg4 = table.Rows[i].GetTableCells()[j + 1].Paragraphs[0];                           XWPFRun run4 = pg4.CreateRun();                           run4.SetText(ganBu.ZaiZhiJiaoYu_XueLi);                           run4.AddBreak();                           run4.SetText(ganBu.ZaiZhiJiaoYu_XueWei);                           break;                       case "现任职务":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.XianRenZhiWu);                           break;                       case "拟任职务":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.NiRenZhiWu);                           break;                       case "拟免职务":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.NiMianZhiWu);                           break;                       case "简历":                           int lastLine = 1;                           XWPFParagraph pg5 = table.Rows[i].GetTableCells()[j + 1].Paragraphs[0];                           XWPFRun run5 = pg5.CreateRun();                           foreach (JianLi jl in ganBu.JianLi)                           {                               if (lastLine != ganBu.JianLi.Count)                               {                                   if (ifFirst)                                   {                                       run5.SetText(jl.KaiShiNianYue + "--" + jl.JieSuNianYue + "  " + jl.JingLi);                                       ifFirst = false;                                   }                                   else                                   {                                       table.Rows[i].GetTableCells()[j + 1].AddParagraph().CreateRun().SetText(jl.KaiShiNianYue + "--" + jl.JieSuNianYue + "  " + jl.JingLi);                                   }                                   lastLine++;                               }                               else                               {                                   table.Rows[i].GetTableCells()[j + 1].AddParagraph().CreateRun().SetText(jl.KaiShiNianYue + "--" + "    " + jl.JieSuNianYue + "    " + jl.JingLi);                               }                           }                           break;                       case "奖惩情况":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.JiangChengQingKuang);                           break;                       case "年核度结考果":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.NianDuKaoHeJieGuo);                           break;                       case "任免理由":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.RenMianLiYou);                           break;                       case "家庭主要成员及重要社会关系":                           List<JiaTingChengYuan> jtcyList = ganBu.JiaTingChengYuan;                           for (int m = 0; m < jtcyList.Count(); m++)                           {                               XWPFTableRow tr = table.Rows[i + m + 1];                               tr.GetTableCells()[1].SetText(jtcyList[m].ChengWei);                               tr.GetTableCells()[2].SetText(jtcyList[m].XingMing);                               tr.GetTableCells()[3].SetText(jtcyList[m].NianLing.ToString());                               tr.GetTableCells()[4].SetText(jtcyList[m].ZhengZhiMianMao);                               tr.GetTableCells()[5].SetText(jtcyList[m].GongZuoDanWeiJiZhiWu);                            }                           break;                       case "呈报单位":                           table.Rows[i].GetTableCells()[j + 1].SetText(ganBu.ChengBaoDanWei);                           break;                       case "行任政免机意关见":                           table.Rows[i].GetTableCells()[j + 1].SetText(" 同意 " );                           break;                   }               }           }           num++;       }            System.IO.FileStream output = new System.IO.FileStream(targetFilePath, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite);       //写入文件       docx.Write(output);        output.Close();       output.Dispose();        logger.Info(targetFilePath + "文件生成成功!");   }   catch (Exception ex)   {       logger.Error(filename + "转换不成功");       logger.Error(ex.ToString());    } 

        2 核心思路和注意点

         2.1 需要填充内容位置判断:

            通过遍历表格中的文字内容来判断,填充的位置就是文字所在单元格位置横向+1 了。

        2.2 需要注意点:

                年度考核结果实际在解析模板中对应字符串为 "年核度结考果", 同样的还有行政任免机关意见对应为“行任政免机意关见” ,这个是个坑。

  总结:

        有些点说通了,会发现实现起来就没什么难度了。批量转换以及子目录这些我就不阐述了。 东西写得也比较粗,如果有需要的朋友可以留言给我,一起完善这个软件了。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!