最近在帮助公司里做一些简历解析的活,与公司合作的招聘网站有猎聘、前程无忧、卓博、中国人才热线、智联共5家,人资给到了这5个网站的简历模板,都是doc档,要求能自动解析并上传到公司的eHR系统,花了大概2天时间终于搞定,这其中的几个关键点记录下来,希望能帮到碰到同样问题的人。
因为之前用到了Aspose.doc组件,所以解析doc档首先想到的就是用这个组件,不得不说这个组件很强大,2行代码就可以读到doc里面的内容
Aspose.Words.Document doc = new Aspose.Words.Document(filePath); string m_strResumeText = doc.ToTxt();
这段代码可以解析猎聘、中国人才热线、智联的简历,但是前程无忧和卓博的简历却报错了,提示Unknown file format.一开始我怀疑是组件的问题,以为不是最新版,这个想法没法验证,因为要获取Aspose.Words这个组件的最新版本需要付费。于是我就找他免费的组件,包括NPOI,DocX,这两个试过都不太行,甚至不能打开之前Aspose.dll能打开的3种格式的简历,后来就找到了冰蓝科技的Spire.Doc,这个是免费的,其免费版有限制,如下
不过对于简历来说,不会超过500个段落和25个表格,完全可以使用。这个组件使用也很简单,也是简单的几句话就可以将Doc里的文本提取出来,可是同样的在解析前程无忧和卓博的简历也报错了,提示的信息是:this is not a structured storage file. 有点绝望,这时只能怀疑真的是前程无忧和卓博的简历格式有问题,可是用Word打开却又是正常的,表面看完全看不出格式有问题。
进一步查找,网上有人讲前程无忧的简历其实不是真的doc,而是mht,于是改后缀为mht,用记事本打开,才知道原来内容都编码为了base64,怪不得Aspose.Words和Spire.Doc都打不开。
找到了原因,接下来就是尝试解决方案了,先以二进制流的方式打开文件,然后转化为字符串,然后在GitHub上找了一个MHTMLParser的类库,将字符串中以base64编码的内容解码,以解码后的内容重新生成doc文件,这时就可以用Aspose.Doc打开了。
Stream sFile = new FileStream(hidFilePath.Value, FileMode.Open); byte[] bytes = new byte[sFile.Length]; sFile.Read(bytes, 0, bytes.Length); sFile.Close(); string charset = ""; if (m_strTemplateCode == "51job") { charset = "gb2312"; } if (m_strTemplateCode == "jobcn") { charset = "utf-8"; } var byteToString1 = System.Text.Encoding.GetEncoding(charset).GetString(bytes); MHTMLParser parser = new MHTMLParser(byteToString1); string html = parser.getHTMLText(); if (!html.StartsWith("<html><body>")) { html = "<html><body>" + html + "</html></body>"; } byte[] bytes2 = System.Text.Encoding.GetEncoding("gb2312").GetBytes(html); string tempFilePath = Path.Combine(Server.MapPath("/Upload"), m_strTemplateCode + DateTime.Now.ToString("HHmmsss") + ".doc"); FileStream fs = new FileStream(tempFilePath, FileMode.CreateNew); fs.Write(bytes2, 0, bytes2.Length); fs.Close(); doc = new Aspose.Words.Document(tempFilePath); m_strResumeText = doc.ToTxt();
注意上述代码中有以下段,这一段很重要,如果没有<html><body>这样的标记,Aspose.doc还是解析不了。
if (!html.StartsWith("<html><body>")) { html = "<html><body>" + html + "</html></body>"; }
在解析过程中,发现提取的txt文件中包括很多的重复行内容,可以先将行用特殊字符替换(如^),然后用以下这句话就可以将重复的内容去除了。
m_strResumeText = String.Join("^", m_strResumeText.Split(\'^\').Distinct());
在取到简历文档的txt后,这时就可以用正则表达式提取每个字段的内容了
循环这些正则表达式规则,取每个栏位的值,然后就可以保存至数据库了。