用C#写一个Excel转Txt的小工具

在游戏制作过程中,策划通常喜欢用EXCEL进行数据编辑。但是直接读取EXCEL文档对于程序来说并不是件有效率的工作。通常我们是现将EXCEL保存成TXT或者XML文档,再进行处理。

下面的程序就是用C#编写的批量将一个目录下(包括子目录)的所有EXCEL文件转换为TXT文档的小工具。为了使TXT文档相对美观做了一些处理(按列对齐)。

完整代码:http://pan.baidu.com/s/1o6oKSH0

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data.SqlTypes;

using Microsoft.Office.Core;

using Excel = Microsoft.Office.Interop.Excel;

namespace excel2txt
{
    class Program
    {
        static bool _isVerbose = false;
        static bool _isAllian = false;

        // 获得字段的实际最大长度
        static int GetMaxLength(DataTable dt, string captionName)
        {
           DataColumn maxLengthColumn = new DataColumn();
           maxLengthColumn.ColumnName = "MaxLength";
           maxLengthColumn.Expression = String.Format("len(convert({0},'System.String'))", captionName);
           dt.Columns.Add(maxLengthColumn);
           object maxLength = dt.Compute("max(MaxLength)", "true");
           if (maxLength == DBNull.Value)
           {
               return 0;
           }
           dt.Columns.Remove(maxLengthColumn);

           return Convert.ToInt32(maxLength);
        }

        static void convertExcelToTxt(string inputFile, string outputPath)
        {
            if (Path.GetExtension(inputFile) != ".xls" && Path.GetExtension(inputFile) != ".xlsx")
            {
                return;
            }

            if(!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            string newFileNameNoExt = Path.GetFileNameWithoutExtension(inputFile);
            string newFileNoExt = outputPath + "\\" + newFileNameNoExt;
            string newFile = newFileNoExt + ".txt";
            Console.WriteLine("Convert file[{0}] to [{1}]", inputFile, newFile);

            var conn = new OleDbConnection();
            conn.ConnectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;" +
                @"Data Source={0}" +
                ";Extended Properties=\"Excel 12.0 Xml;HDR=No;IMEX=1\"", inputFile);
            conn.Open();
            DataTable sheetTb = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
            foreach (DataRow sheet in sheetTb.Rows)
            {
                string tableName = sheet["TABLE_NAME"].ToString();

                string sql = String.Format("select * from [{0}]", tableName);
                OleDbDataAdapter da = new OleDbDataAdapter(sql, conn);
                
                var ds = new DataSet();
                da.Fill(ds);
                
                var tb1 = ds.Tables[0];
                
                if (tb1.Rows.Count == 0)
                {
                    continue; // 空表
                }
                if ( tb1.Rows.Count == 1 && tb1.Columns.Count == 1)
                {
                    if (tb1.Rows[0][0] == DBNull.Value)
                    {
                        continue; // 空表
                    }
                }

                FileStream fs = new FileStream(newFileNoExt + "_" + tableName.Trim('$') + ".txt", FileMode.OpenOrCreate);
                StreamWriter sw = new StreamWriter(fs);

                int[] colMaxLen = new int[tb1.Columns.Count];

                if (_isAllian)
                {
                    for (int i = 0; i < tb1.Columns.Count; ++i)
                    {
                        colMaxLen[i] = 0;
                        for (int j = 0; j < tb1.Rows.Count; ++j)
                        {
                            string s = tb1.Rows[j][i].ToString();
                            int len = System.Text.Encoding.Default.GetBytes(s).Length;
                            if (len > colMaxLen[i])
                            {
                                colMaxLen[i] = len;
                            }
                        }

                    }
                }
                

                foreach (DataRow row in tb1.Rows)
                {
                    for (int j = 0; j < tb1.Columns.Count; ++j)
                    {
                        DataColumn col = tb1.Columns[j];
                        string content = row[j].ToString();
                        
                        bool hasYinhao = false;
                        if (-1 != content.IndexOf("\r") || -1 != content.IndexOf("\n"))
                        {
                            hasYinhao = true;
                        }
                        
                        string fmt;
                        if (_isAllian) 
                        {
                            int realLen = colMaxLen[j] - (System.Text.Encoding.Default.GetBytes(content).Length - content.Length);
                            // "{0,-10}"\t
                            fmt = String.Format("{0}{1}0,-{2}{3}{4}{5}", hasYinhao ? "\"" : "",
                            "{", realLen, "}", hasYinhao ? "\"" : "", j + 1 == tb1.Columns.Count ? "" : "\t");
                        }
                        else
                        {
                            // "{0}"\t
                            fmt = String.Format("{0}{1}0{2}{3}{4}", hasYinhao ? "\"" : "",
                            "{", "}", hasYinhao ? "\"" : "", j + 1 == tb1.Columns.Count ? "" : "\t");
                        }
                        
                        sw.Write(fmt, row[j]);
                        if (_isVerbose)
                        {
                            Console.Write(fmt, row[j]);
                        }
                    }
                    sw.WriteLine();
                    if (_isVerbose)
                    {
                        Console.WriteLine();
                    }

                }
                sw.Close();
            }
            conn.Close();
        }

        static void loopDir(string inputDir, string outDir)
        {
            DirectoryInfo di = new DirectoryInfo(inputDir);
            var files = di.GetFiles();
            foreach (var file in files)
            {
                string srcPath = file.FullName;
                string dstPath = outDir;
                // Console.WriteLine(srcPath + "         " + dstPath);
                convertExcelToTxt(srcPath, dstPath);
            }

            var infos = di.GetDirectories();
            foreach(var info in infos)
            {
                string srcPath = info.FullName;
                string dstPath = outDir + "\\" + info.Name;
                loopDir(srcPath, dstPath);
            }
        }

        static int Main(string[] args)
        {
            if(args.Length < 1)
            {
                Console.WriteLine("Help: \r\n" +
                    " excel_convert InputDir [OutputDir] /v /a\r\n" +
                    " InputDir 必选,输入目录。 将遍历此目录下的所有.xls 和.xlsx文件进行转换 \r\n" +
                    " Output   可选,输出目录。 如果没有使用和InputDir同一目录 \r\n" +
                    " /v       可选,显示转换信息。\r\n" +
                    " /a       可选,对齐列打印。\r\n");
                return -1;
            }
            string inputDir = args[0];
            if (!Directory.Exists(inputDir))
            {
                Console.WriteLine("No input directory exist, {0}", inputDir);
                return -1;
            }

            string outputPath;
            if (args.Length > 1)
            {
                outputPath = args[1];
            }
            else
            {
                outputPath = inputDir;
            }

            for (int i = 2; i < args.Length; ++i )
            {
                string verbose = args[i];
                verbose = verbose.ToLower();
                if (verbose == "/v")
                {
                    _isVerbose = true;
                }
                if (verbose == "/a")
                {
                    _isAllian = true;
                }
            }
            loopDir(inputDir, outputPath);
            return 0;
        }
    }
}




参考:
1. 【C#读取Excel 2010】,汪宇杰
2. 【C#格式化字符串中转义大括号“{}”】, ^_^肥仔John
3. 【浅谈  DataSet   的用法】
4. 【C#解决汉字长度判断的问题】,米猫腻
5. 【处理 Null 值
6. 【通过ADO连接到EXCEL后如何获取EXCEL里的sheet名
7. 【ADO.NET读取Excel数据时出现有的数据读出来为空】

你可能感兴趣的:(用C#写一个Excel转Txt的小工具)