前言:
公司最近整理文档,老板安排我一个任务将接近1000个的文档的名称提取出来放在Excel表格中,只需要.doc或.docx的文件
这么多个文件可能不能一个一个复制粘贴啊,快速的方法就是写个脚本
分析
于是,我开始分析这些文件,文件夹里面有文件,文件夹里面还有文件夹,于是我想到递归
文件名称的格式是这样的,类似这样
1001001001_A_XXX承认书
- 1001001001,表示编号
- A,表示版本号,可能是A,B,C,依次类推
- XXX承认书,表示名称
很多文件名称就是上面的格式,但是有很多文件名称没有完全按照上面的格式来,毕竟有很多文件,还有不同文件有不同人创建的
于是我就要考虑很多种情况了,
继续分析文件名
有些文件名是这样的
1001001001 XXX承认书,直接没有版本号,(没有版本号的默认A)
也有些文件名是这样的
1001001001A XXX承认书
也有些文件名是这样的
1001001001XXX承认书 (直接是编号+名称)
还有一个问题就是有些编号是9位的,大多都是10位的
且编号与版本号,版本号与名称的分隔符不一定都是“_”,也有“-”和“ ”
实现
先创建一个Model来存储内容
class Model
{
public string Num { get; set; }//编号
public string Ver { get; set; }//版本号
public string Name { get; set; }//名称
}
传入一个路径,用递归遍历文件夹的所有文件
/// <summary>
/// 获取文件夹
/// </summary>
/// <param name="path"></param>
private void GetDire(string path)
{
GetFiles(path);
string[] sonDires = Directory.GetDirectories(path);
if (sonDires.Length > 0)
{
foreach (string dire in sonDires)
{
GetDire(dire);
}
}
}
获取文件夹下的所有文件
/// <summary>
/// 获取文件夹下的所有文件
/// </summary>
private void GetFiles(string path)
{
string[] files = Directory.GetFiles(path);
foreach (string file in files)
{
//获取文件名
string fileName = file.Substring(file.LastIndexOf("\\") + 1);
GetFile(path, fileName);
}
}
创建存储数据
Model model;
List<Model> list = new List<Model>();
解析
接下来就是解析文件了
根据上面的分享需要用到几个判断方法
分别判断字符是否汉字,是否数字,是否字母,判断分隔符是否" ","-","_"
/// <summary>
/// 判断是否汉字
/// </summary>
private bool IsChinese(string value)
{
Regex rg = new Regex("^[\u4e00-\u9fa5]$");
return rg.IsMatch(value);
}
/// <summary>
/// 判断是否数字
/// </summary>
private bool IsNumber(string value)
{
Regex rg = new Regex("^[0-9]$");
return rg.IsMatch(value);
}
/// <summary>
/// 判断是否字母
/// </summary>
private bool IsWord(string value)
{
Regex rg = new Regex("^[a-zA-Z]$");
return rg.IsMatch(value);
}
/// <summary>
/// 判断字符" ","-","_"
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private bool IsSpace(string value)
{
return (value.Contains(" ") || value.Contains("-") || value.Contains("_"));
}
解析获取文件
/// <summary>
/// 获取特定的文件
/// </summary>
private void GetFile(string path, string fileName)
{
//不是.doc和.docx的文件不添加
if (Path.GetExtension(fileName) != ".doc" && Path.GetExtension(fileName) != ".docx")
{
return;
}
//特殊文件不添加
if (fileName.StartsWith("~") || fileName.Contains("xxxxxxxx"))
{
return;
}
//文件名第一个字符不为数字,不添加
if (!IsNumber(fileName.Substring(0, 1)))
{
return;
}
//提取名称,不含扩展名
fileName = fileName.Substring(0, fileName.LastIndexOf("."));
model = new Model();
#region 编号
string Num10 = fileName.Substring(0, 10);
int numLastIndex = 10;//编号的最后一个在名称中的索引
//10位编号
if (long.TryParse(Num10, out long num))
{
model.Num = Num10;
}
else//9位编号
{
string Num9 = fileName.Substring(0, 9);
if (long.TryParse(Num9, out long num2))
{
model.Num = Num9;
}
numLastIndex = 9;
}
#endregion
string numNext = fileName.Substring(numLastIndex, 1);//编号的下一个字符
string verNext = fileName.Substring(numLastIndex + 2, 1);//版本的下一个字符
//编号后且名称前是" ","-","_"
if (IsSpace(numNext) && IsSpace(verNext))//类似 1001001001-A XXX承认书
{
model.Ver = fileName.Substring(numLastIndex + 1, 1);
int nameStartIndex = numLastIndex + 3;
model.Name = fileName.Substring(nameStartIndex, fileName.Length - nameStartIndex);
}
//编号后是" ","-","_",名称前不是,则没有版本号
else if (IsSpace(numNext) && !IsSpace(verNext))//类似 1001001001 XXX承认书
{
int nameStartIndex = numLastIndex + 1;
model.Name = fileName.Substring(nameStartIndex, fileName.Length - nameStartIndex);
model.Ver = "A";
}
else
{
verNext = fileName.Substring(numLastIndex + 1, 1);
if (IsWord(numNext) && IsSpace(verNext))//1001001001A XXX承认书
{
model.Ver = numNext;
int nameStartIndex = numLastIndex + 2;
model.Name = fileName.Substring(nameStartIndex, fileName.Length - nameStartIndex);
}
else if (IsChinese(verNext = fileName.Substring(numLastIndex, 1))) //1001001001XXX承认书 (直接是编号+名称)
{
model.Name = fileName.Substring(numLastIndex, fileName.Length - numLastIndex);
model.Ver = "A";
}
else
{
}
}
//有重复编号不添加
foreach (Model item in list)
{
if (item.Num == model.Num)
{
return;
}
}
list.Add(model);
}
还没完,接下来就是将获取的list写入Excel表格中
昨天刚学习了,C#操作Excel表格,今天就派上用场了,真爽
C#使用Microsoft.Office.Interop.Excel.操作Excel表格
用这方法需要导入Microsoft.Office.Interop.Excel.dll,在上面链接中可以下载
传入要导出的Excel表格路径
private void DataToExcel(string fileName)
{
//应用程序
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
//工作簿
Workbook wbk = app.Workbooks.Open(fileName);
//工作表
Worksheet wsh = wbk.Sheets["Sheet1"];
//写入数据
for (int i = 0; i < list.Count; i++)
{
wsh.Cells[i + 1, 1] = list[i].Num;
wsh.Cells[i + 1, 2] = list[i].Name;
wsh.Cells[i + 1, 5] = list[i].Ver;
}
//保存
wbk.Save();
//退出
app.Quit();
//释放
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
}