Преобразование Excel в CSV с новой строкой и разрыв строки внутри столбца - PullRequest
0 голосов
/ 05 января 2019

Попытка преобразовать файл xlsx в csv с помощью кода C #. Я могу успешно преобразовать файл, но он не может правильно обрабатывать перевод строки и перенос строки. Посоветуйте, пожалуйста, какой разделитель использовать, чтобы мой 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. Третья строка

точка Excel, то есть 1, 2 и 3 находятся в одном столбце, но разные строки

Ожидаемый выходной формат CSV 1. Первая строка 2. Вторая строка 3. Третья строка

Пожалуйста, помогите

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Основной проблемой здесь является наиболее распространенная проблема, возникающая у людей при обработке файлов CSV: они думают, что все, что требуется, - это объединить значения запятыми и поставить новую строку в конце каждой строки. Есть дополнительные случаи, о которых они не думают, как:

  1. Что если значение содержит символ новой строки?
  2. Что если значение содержит запятую?
  3. Как только они преодолеют 1 и 2, что, если значение содержит "?

Я бы предположил, что наилучшим подходом будет использование библиотеки для создания файла CSV. Но если вы не хотите этого делать, вот несколько советов, которые могут улучшить ситуацию:

  1. Каждое значение должно быть заключено в " символов.
  2. В результате точки 1, символы " в значении должны быть экранированы символом обратной косой черты перед ними.
  3. Объявление a не отображается, но я предполагаю, что это строка. Строки являются неизменяемыми, поэтому следует использовать System.Text.StringBuilder для создания строки.
  4. Код в вопросе всегда будет заканчиваться дополнительной запятой в конце каждой строки. Попробуйте использовать string.Join для ввода запятых между значениями, чтобы не ставить их в конце.
  5. Stream s IDisposable, поэтому каждый из них должен быть в блоке using. После этого вам не нужно закрывать поток, так как он будет закрыт неявным Dispose при выходе из блока.
  6. Вместо while (row_no < result.Tables[0].Rows.Count) предпочитают foreach (DataRow dataRow in result.Tables[0].Rows). Проще прочитать, что делает цикл, и поместить строку в локальную переменную, а не выполнять поиск свойства для Tables, поиск индексатора для таблицы, поиск свойства для Rows и индексатора поиск каждый раз в цикле. И это облегчает чтение содержимого цикла.
  7. Используйте System.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());
}

Я не за своим ПК, так что если у меня есть опечатки или ошибки с автозаменой в приведенном выше примере, я немного расслаблюсь. Также: я опустил определение метода string Escape(string v), который должен делать то, что описано в моем пункте 2.

0 голосов
/ 05 января 2019

, если вы хотите

         +-------+-------+-----+-----+-----+
         |  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";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...