在列中使用新行和换行符将Excel转换为CSV

时间:2019-01-05 05:23:02

标签: c# asp.net excel csv

尝试通过C#代码将xlsx文件转换为csv。我能够成功转换文件,但无法正确处理换行符和换行符。 请建议使用哪个分隔符,以便正确生成我的csv

csv转换代码无法正确转换。它应该完全完成列的转换,但没有完成。

使用以下代码将xlsx文件转换为csv

string file= @"fakepath\abc.xlsx";

DataSet result = new DataSet();

//------To read the xlsx file
if (file.EndsWith(".xlsx"))
            {
                // Reading from a binary Excel file (format; *.xlsx)
                FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read);
                IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
                result = excelReader.AsDataSet();
                excelReader.Close();
            }

//-------To convert the file into csv format
while (row_no < result.Tables[0].Rows.Count)
            {
                for (int i = 0; i < result.Tables[0].Columns.Count; i++)
                {
                    a += result.Tables[0].Rows[row_no][i].ToString() + ",";
                }
                row_no++;
                a += "\r\n";
            }

string output = @"fakepath\abc.csv";
            StreamWriter csv = new StreamWriter(@output, false);
            csv.Write(a);
            csv.Close();

Excel中的列将数据保存为

  
      
  1. 第一行

  2.   
  3. 第二行

  4.   
  5. 第三行

  6.   

excel点,即1,2和3在同一列但不同行

预期的输出csv格式 1.第一行2.第二行3.第三行

请帮助

2 个答案:

答案 0 :(得分:0)

如果您想要的是

         +-------+-------+-----+-----+-----+
         |  a    |       |     |     |     |
         |  b    |       |     |     |     |
         |  c    |       |     |     |     |
         +---------------------------------+
         |  d    |       |     |     |     |
         |  e    |       |     |     |     |
         |  f    |       |     |     |     |
         +---------------------------------+
         |  g    |       |     |     |     |
1        |  h    |       |     |     |     |
         |       |       |     |     |     |
         +---------------------------------+
         |       |       |     |     |     |


         +-------+------+------+-----+-----+
         |  a    |   b  |   c  |     |     |
         |       |      |      |     |     |
         +---------------------------------+
         |  d    |  e   |  f   |     |     |
         |       |      |      |     |     |
         +---------------------------------+
         |  g    |  h   |      |     |     |
 2       |       |      |      |     |     |
         +---------------------------------+
         |       |      |      |     |     |
         |       |      |      |     |     |


         +-------+------+------+-----+-----+
         |  abc  |      |      |     |     |
         |       |      |      |     |     |
         +---------------------------------+
         |  def  |      |      |     |     |
 3       |       |      |      |     |     |
         +---------------------------------+
         |  gg   |      |      |     |     |
         |       |      |      |     |     |
         +---------------------------------+
         |       |      |      |     |     |

使用1到2次

var column = result.Tables[0].Rows[row_no][i].ToString();
column.Split(new[] { '\r', '\n' }).ToList()
.ForEach(column_line => { a += column_line + ","; });

使用1到3次

var column = result.Tables[0].Rows[row_no][i].ToString();
a += String.Join(" ", column.Split(new[] { '\r', '\n' }));

也可以使用1到3个

var column = result.Tables[0].Rows[row_no][i].ToString();
column = column.Replace("\r", " ");
a+= column.Replace("\n", " ");

完整代码

string file = @"fakepath\abc.xlsx";

DataSet result = new DataSet();

//------To read the xlsx file
if (file.EndsWith(".xlsx"))
{
    // Reading from a binary Excel file (format; *.xlsx)
    FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read);
    IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
    result = excelReader.AsDataSet();
    excelReader.Close();
}

//-------To convert the file into csv format
while (row_no < result.Tables[0].Rows.Count)
{
    for (int i = 0; i < result.Tables[0].Columns.Count; i++)
    {
        var column = result.Tables[0].Rows[row_no][i].ToString();
        //column.Split(new[] { '\r', '\n' }).ToList().ForEach(column_line => { a += column_line + ","; });
        or
        a+=String.Join(" ", column.Split(new[] { '\r', '\n' }));
        //or
        //column = column.Replace("\r", " ");
        //a+= column.Replace("\n", " ");

    }
    row_no++;
    a += Environment.NewLine;
    //or
    // a += "\r\n";
}

string output = @"fakepath\abc.csv";
StreamWriter csv = new StreamWriter(@output, false);
csv.Write(a);
csv.Close();

更多

a +=Environment.NewLine

代替

 a +="\r\n";

答案 1 :(得分:0)

这里的主要问题是人们在处理CSV文件时遇到的最常见问题:他们认为所需要做的就是用逗号将值连接起来,并在每行的末尾添加换行符。他们没有想到一些边缘情况:

  1. 如果值包含换行符怎么办?
  2. 如果值包含逗号怎么办?
  3. 一旦他们克服了1和2,如果值包含"会怎样?

我建议最好的方法是使用一个库来帮助创建CSV文件。但是,如果您不想这样做,可以参考以下建议,这些建议可能会有所改善:

  1. 每个值都必须用"字符括起来。
  2. 作为点1的结果,值中的"个字符需要在其前面加上反斜杠字符进行转义。
  3. a的声明未显示,但我认为它是一个字符串。字符串是不可变的,因此您should use System.Text.StringBuilder来构造字符串。
  4. 问题中的代码总是在每行末尾加一个逗号。考虑使用string.Join将逗号放在值之间,这样一来您就不会得到逗号结尾。
  5. Stream是可分配ID的,因此每个对象都应位于using块中。完成此操作后,您无需关闭流,因为它在退出该块时将被隐式Dispose关闭。
  6. 而不是while (row_no < result.Tables[0].Rows.Count)更喜欢foreach (DataRow dataRow in result.Tables[0].Rows)。读取循环正在执行的操作并将其放入局部变量中比较容易,而不必进行Tables的属性查找和表的索引器查找以及{{1}的属性查找每次在循环中查找索引器。而且它使循环的内容更易于阅读。
  7. 优先使用RowsSystem.Environment.NewLine。再次,这只是化妆品,使其易于阅读。

那会给你...

"\r\n"

我不在电脑上,所以如果上面有错别字或自动更正错误,请给我一些放松。另外:我已经省略了方法string file= @"fakepath\abc.xlsx"; DataSet result = new DataSet(); //------To read the xlsx file if (file.EndsWith(".xlsx")) { // Reading from a binary Excel file (format; *.xlsx) using (FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read)) { IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); result = excelReader.AsDataSet(); excelReader.Close(); } } //-------To convert the file into csv format var a = new StringBuilder(); int columnCount=result.Tables[0].Columns.Count; foreach (DataRow dataRow in result.Tables[0].Rows) { var values=new List<string>(columnCount); for (int i = 0; i < columnCount; i++) { values.Add(dataRow[i].ToString()); } string line=string.Join(",", values.Select(v=>$"\"{Escape(v)}\""); a.AppendLine(line); // even neater than Environment.NewLine } string output = @"fakepath\abc.csv"; using(StreamWriter csv = new StreamWriter(@output, false)) { csv.Write(a.ToString()); } 的定义,该方法需要执行我在第2点中描述的内容。