【问题标题】:How do I automate saving of .csv files to delimited .txt files using C#?如何使用 C# 自动将 .csv 文件保存到分隔的 .txt 文件?
【发布时间】:2014-03-12 23:22:32
【问题描述】:

我有大约 23 个 .csv 文件。我在 Excel 中将它们全部打开,然后在 Excel 中手动将它们保存为制表符分隔的 .txt。我该如何自动化这个过程?

简单地说,我想使用 C# winform 将 .csv 文件转换为制表符分隔的 .txt 文件,我可以在其中按下一个按钮并让我的 C:\csv\ 文件夹中的所有 .csv 文件自动转换为制表符分隔的 .txt 文件。

我对通过更改扩展名简单地将 .csv 文件重命名为 .txt 文件犹豫不决,因为在此过程中似乎发生了一些变化。准确地说,我的程序在读取扩展名已重命名并从 .csv 更改为 .txt 的文本文件时遇到错误,但在读取已通过 Excel 从 .csv 转换为分隔的 .txt 的文本文件时不会遇到错误.我认为这是因为我在 Excel 中将它们保存为制表符分隔的文本。

【问题讨论】:

    标签: c# excel csv


    【解决方案1】:

    此解决方案假定您的文件都相对较小,如果将整个文件一次加载到内存中,则不会导致OutOfMemoryExceptions

      DirectoryInfo dir = new DirectoryInfo(@"C:\path\to\root");
      FileInfo[] files = dir.GetFiles();
    
      foreach (string path in files.Where(x => x.Extension == "csv").Select(x => x.FullName))
      {
          string input = File.ReadAllText(path);
          File.WriteAllText(input.Replace(',', '\t')
      }
    

    另外,关于你的最后一段的几点说明; .csv 和 .txt 文件之间没有区别。它们都是纯文本文件。 csv 只是代表“逗号分隔值”我可以有一个技术上是“csv”的文本文件,我可以有一个内容实际上不是格式的 .csv 文件。更改扩展名不会神奇地将逗号自己重写为制表符,但如果您的代码可以读取原始 csv 格式,则没有理由无法正常工作。

    编辑:结合更多的东西;首先,我更新了示例代码,使其使用目录路径作为起点并从那里获取所有文件。其次,只是不想,如果您的文件对于此解决方案来说太大,请在同一个 foreach 循环中使用 StreamReader/StreamWriter。 msdn 有一个充分的例子,所以我不会在这里发布任何内容,您只需逐行读取文件,用制表符替换逗号,将行写入输出文件。

    使用 csv 阅读器进行更稳健的转换;

     using System.IO;
     using LumenWorks.Framework.IO.Csv;
    
     List<string> output = new List<string>();
    
    // open the file "data.csv" which is a CSV file with headers
    using (CsvReader csv =
           new CsvReader(new StreamReader("data.csv"), true))
    {
        int fieldCount = csv.FieldCount;
    
        string[] headers = csv.GetFieldHeaders();
        while (csv.ReadNextRecord())
        {
            output.Add(String.Join("\t", csv.NotSureWhatThisPropertyNameShouldBe));
        }
    }
    

    CsvReader 类为您提供了每行中的值的索引器,但我不确定您将使用什么属性来获取整行字符串数组,例如上面的意图。

    【讨论】:

    • 嗯,这看起来很有帮助,为什么有人会否决它为-1?埃文,我忘了提到该文件夹​​可能包含各种不同的文件类型。如何确保只有以 .csv 或 .xls 或 .xlsx 结尾的文件才能转换为 .txt?
    • @phan 这本身就是一个不同的问题,但是使用 DirectoyInfo 类来获取目标目录中所有文件的 FileInfo 实例,然后您可以使用简单的 LINQ 查询进行过滤仅适用于 .csv、.xls 和 .xlsx 文件。此外,您对 csv 文件所做的操作不一定适用于这些 Excel 格式。我对它们并不了解,但我很确定文件中包含大量元数据,这将使其与 csv 等效文件大不相同。
    • 关于否决者我不能说,因为他们不想发表评论。他们可能有一些有效的担忧,但很可能他们只是个白痴,因为这个答案给了你基本的想法。是的,它还没有准备好企业软件。不,我永远不会在 SO 上提供如此强大的代码的答案。
    • @phan 一个问题;文件中的值可以包含逗号吗?例如,我可以有类似val1,"value2, is a sentence, with commas!",val3 的东西,因为这显然会使代码无法工作,如果是这种情况,问题会更复杂,我建议使用 csv 解析器。
    • 在我的脑海中,我不确定,但这是可能的。我了解您正在用制表符替换逗号,并试图模仿 Excel 在将数据保存为分隔文本时所做的事情。我想知道是否有另一种方法可以自动化 excel 将数据保存为分隔文本的方法
    【解决方案2】:

    如果您愿意使用 Interop:

    using Microsoft.Office.Interop.Excel;
    using System.IO;
    using System;
    
    public class ExcelInterop : IDisposable
    {
        private Application _excelApplication;
    
        public ExcelInterop()
        {
            _excelApplication = new Application();
        }
    
        public void ConvertDirectoryOfCsvFilesToTxt(string inputFolder, string outputFolder)
        {
            var files = Directory.GetFiles(seasonPath).Where(f => !f.EndsWith(".csv")).ToList();
    
            foreach(string file in files)
            {
                string outFilePath = Path.Combine(outputFolder, Path.GetFileNameWithoutExtension(file) + ".txt";
                ConvertCsvToTxt(file, outFilePath));
            }
        }
    
        private void ConvertCsvToTxt(string inputFilePath, string outputFilePath)
        {
            Workbook workbook = _excelApp.Workbooks.Open(inputFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            workbook.SaveAs(outputFilePath, XlFileFormat.xlCurrentPlatformText, Type.Missing, Type.Missing, false);
            workbook.Close();
            Marshal.ReleaseComObject(workbook);
        }
    
        public void Dispose()
        {
            _excelApplication.Quit();
            Marshal.ReleaseComObject(_excelApplication);
        }
    }
    

    部分基于DotNetPerlsVbCity 加上我自己对Interop 的回忆。这是在文本文件中编写的,可能无法编译或正常工作,但应该可以帮助您入门。

    你可以这样称呼它

    using(ExcelInterop excelInterop = new ExcelInterop())
    {
        excelInterop.ConvertDirectoryOfCsvFilesToTxt("C:\\csv", "C:\\txt");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      • 2022-10-16
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      相关资源
      最近更新 更多