Смена разделителя столбцов в CSV с помощью C#

cherus09

Client
Регистрация
10.10.2016
Сообщения
172
Благодарностей
14
Баллы
18
Привет, подскажите как при создании файла CSV при помощи C# задать произвольный разделитель столбцов? Сейчас у меня по умолчанию стоит разделитель по ";" что для меня не удобно так ка в спаршеном тексте пободается данный символ из-за чего не правильно записываются данные в таблицу.
Таблицу создаю сразу с заголовками столбцов вот такой строчкой:
C#:
File.AppendAllText(patchFaileOut, "Дата выхода статьи; Заголовок; Текст; URL Imag-1" + Environment.NewLine, Encoding.UTF8);
 

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 518
Благодарностей
3 370
Баллы
113
Используйте таблицы и в их настройках укажите иной разделитель.
 

cherus09

Client
Регистрация
10.10.2016
Сообщения
172
Благодарностей
14
Баллы
18
Используйте таблицы и в их настройках укажите иной разделитель.
Это понятно, я думал что можно в CSV как-то указать свой разделитель. Но я так понимаю что нельзя.
 

Yuriy Zymlex

Moderator
Команда форума
Регистрация
24.10.2016
Сообщения
6 518
Благодарностей
3 370
Баллы
113
Это понятно, я думал что можно в CSV как-то указать свой разделитель. Но я так понимаю что нельзя.
Скорее всего возможно, например TAB, главное что бы получатель знал о нём.
И такой способ, в любом случае, не пойдёт.
 

nicanil

Client
Регистрация
06.03.2016
Сообщения
2 242
Благодарностей
1 820
Баллы
113
Попробуйте использовать код из этого сообщения - клик.
На вход подаётся текст одной ячейки (не всей строки!), а на выходе этот же текст, но заключенный в кавычки (если в тексте будут встречены двойный кавычки, то они будут экранированы). Даже если внутри ячейки будет символ-разделитель, то он будет интерпретирован как часть строки, а не разделитель.

В ином случае какой-бы разделитель Вы не выбрали (TAB, запятая, тире, двоеточие... что угодно), он рано или поздно может снова встретиться в спарешнной строке и поломать структуру.
 

cherus09

Client
Регистрация
10.10.2016
Сообщения
172
Благодарностей
14
Баллы
18
Попробуйте использовать код из этого сообщения - клик.
На вход подаётся текст одной ячейки (не всей строки!), а на выходе этот же текст, но заключенный в кавычки (если в тексте будут встречены двойный кавычки, то они будут экранированы). Даже если внутри ячейки будет символ-разделитель, то он будет интерпретирован как часть строки, а не разделитель.

В ином случае какой-бы разделитель Вы не выбрали (TAB, запятая, тире, двоеточие... что угодно), он рано или поздно может снова встретиться в спарешнной строке и поломать структуру.
Спасибо за подсказку но я так и не понял как применить этот код
 

nicanil

Client
Регистрация
06.03.2016
Сообщения
2 242
Благодарностей
1 820
Баллы
113
Спасибо за подсказку но я так и не понял как применить этот код
Этот метод надо добавить в Общий код.

C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;
using ZennoLab.CommandCenter.TouchEvents;
using ZennoLab.CommandCenter.FullEmulation;
using ZennoLab.InterfacesLibrary.Enums;

namespace ZennoLab.OwnCode
{
    class CommonCode
    {
        /// <summary>
        /// Turn a string into a CSV cell output
        /// </summary>
        /// <param name="str">String to output</param>
        /// <returns>The CSV cell formatted string</returns>
        public static string StringToCSVCell(string str)
        {
            bool mustQuote = (str.Contains(",") || str.Contains("\"") || str.Contains("\r") || str.Contains("\n"));
            if (mustQuote)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("\"");
                foreach (char nextChar in str)
                {
                    sb.Append(nextChar);
                    if (nextChar == '"')
                        sb.Append("\"");
                }
                sb.Append("\"");
                return sb.ToString();
            }
        
            return str;
        }
    }
}
Потом, в кубике Свой C# код вызываете вновь добавленный метод отдельно для каждой ячейки
C#:
// В переменной some_value значение для ячейки.
string cell_1 = CommonCode.StringToCSVCell(some_value);
 
  • Спасибо
Реакции: cherus09

cherus09

Client
Регистрация
10.10.2016
Сообщения
172
Благодарностей
14
Баллы
18
Этот метод надо добавить в Общий код.

C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;
using ZennoLab.CommandCenter.TouchEvents;
using ZennoLab.CommandCenter.FullEmulation;
using ZennoLab.InterfacesLibrary.Enums;

namespace ZennoLab.OwnCode
{
    class CommonCode
    {
        /// <summary>
        /// Turn a string into a CSV cell output
        /// </summary>
        /// <param name="str">String to output</param>
        /// <returns>The CSV cell formatted string</returns>
        public static string StringToCSVCell(string str)
        {
            bool mustQuote = (str.Contains(",") || str.Contains("\"") || str.Contains("\r") || str.Contains("\n"));
            if (mustQuote)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("\"");
                foreach (char nextChar in str)
                {
                    sb.Append(nextChar);
                    if (nextChar == '"')
                        sb.Append("\"");
                }
                sb.Append("\"");
                return sb.ToString();
            }
       
            return str;
        }
    }
}
Потом, в кубике Свой C# код вызываете вновь добавленный метод отдельно для каждой ячейки
C#:
// В переменной some_value значение для ячейки.
string cell_1 = CommonCode.StringToCSVCell(some_value);
Не пойму что я делаю не так, вроде все сделал как положено, но ничего не поменялось.
 

cherus09

Client
Регистрация
10.10.2016
Сообщения
172
Благодарностей
14
Баллы
18
Вот так я добавил в Общий код:
C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;
using ZennoLab.CommandCenter.TouchEvents;
using ZennoLab.CommandCenter.FullEmulation;
using ZennoLab.InterfacesLibrary.Enums;
using HtmlAgilityPack;
using System.Xml;

namespace ZennoLab.OwnCode
{
    class CommonCode
    {
        /// <summary>
        /// Turn a string into a CSV cell output
        /// </summary>
        /// <param name="str">String to output</param>
        /// <returns>The CSV cell formatted string</returns>
        public static string StringToCSVCell(string str)
        {
            bool mustQuote = (str.Contains(",") || str.Contains("\"") || str.Contains("\r") || str.Contains(";")|| str.Contains("\n"));
            if (mustQuote)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("\"");
                foreach (char nextChar in str)
                {
                    sb.Append(nextChar);
                    if (nextChar == '"')
                        sb.Append("\"");
                }
                sb.Append("\"");
                return sb.ToString();
            }
        
            return str;
        }
    }

//    /// <summary>
//    /// A simple class of the common code
//    /// </summary>
//    public class CommonCode
//    {
//        /// <summary>
//        /// Lock this object to mark part of code for single thread execution
//        /// </summary>
//        public static object SyncObject = new object();

//        // Insert your code here
//    }
}

namespace yelpPars
{
    public static class Extension
  {
public static string HtmlDecode (this string LineIn)
    {
        return System.Web.HttpUtility.HtmlDecode(LineIn);
    }
    
    public static string FormLine(string numberCompany, string nameCompany, string linkCompany)
    {
    return String.Format("{0};{1};{2}", numberCompany, nameCompany, linkCompany);
    }
  }
}
Вот код кубика который парсит текст и вносит в таблицу:
C#:
string patchFaileOut = project.Directory + @"\articles.csv"; //Путь к таблице статей
 //Проверяем, существует ли таблица со  статьями

if (!File.Exists(patchFaileOut))
{
    File.AppendAllText(patchFaileOut, "Дата выхода стать; Заголовок; Текст; URL Imag-1" + Environment.NewLine, Encoding.UTF8);//Создаем таблицу, если ее нет, прописываем названия столбцов
}

HtmlDocument doc = new HtmlDocument(); // создание объекта
var template_html = project.Variables["get_article"].Value; // грузим наш код
doc.LoadHtml(template_html); // грузим DOM текст (из переменной template_html) в объект doc

string date_article = doc.DocumentNode.SelectSingleNode(".//span[contains(@class, 'article-stat__date')]").InnerText.HtmlDecode();//Парсим дату постинга статьи
project.SendInfoToLog("Парсим дату выхода статьи", true);

if(date_article ==null){
project.SendErrorToLog("Не найдена дата выхода статьи! Проверьте путь xPath!", true);
}

string article_title = doc.DocumentNode.SelectSingleNode(".//h1[contains(@class,'article__title')]").InnerText.HtmlDecode();// Парсим заголовок статьи
project.SendInfoToLog("Парсим заголовок статьи", true);

if(article_title == null){
project.SendErrorToLog("Не найден заголовок статьи! Проверьте путь xPath!", true);
}

string articleMiddle = doc.DocumentNode.SelectSingleNode(".//div[contains(@class,'article-render')]").InnerText.HtmlDecode();//Парсим текст статьи
project.SendInfoToLog("Парсим текст статьи", true);

string cell_1 = CommonCode.StringToCSVCell(articleMiddle);//// В переменной articleMiddle значение для ячейки.

if(articleMiddle == null){
project.SendErrorToLog("Не найден текст статьи! Проверьте путь xPath!", true);
}

    var url_Img = doc.DocumentNode.SelectSingleNode(".//img[contains(@class, 'article-image__image')]").Attributes["data-src"].Value;

if(url_Img == null)
{
project.SendErrorToLog("Не найдены ссылки на изображения! Проверьте путь xPath!", true);
}
List <string> data = new List <string>();//Создаем спиисок для временного хранения данных
string line = String.Format("{0};{1};{2};{3}", date_article, article_title, articleMiddle, url_Img); //Формируем строку для записи данных в список
data.Add(line);//Добавляем спаршенные данные во временный список
File.AppendAllLines(patchFaileOut,data, Encoding.UTF8);//Записывем данные из временного списка в таблицу
 

porileenvej

Client
Регистрация
09.05.2020
Сообщения
99
Благодарностей
131
Баллы
33
Измени 43 строку на
C#:
string line = String.Format("{0};{1};{2};{3}",CommonCode.StringToCSVCell(date_article), CommonCode.StringToCSVCell(article_title), CommonCode.StringToCSVCell(articleMiddle), CommonCode.StringToCSVCell(url_Img));
 
  • Спасибо
Реакции: nicanil и cherus09

cherus09

Client
Регистрация
10.10.2016
Сообщения
172
Благодарностей
14
Баллы
18
Измени 43 строку на
C#:
string line = String.Format("{0};{1};{2};{3}",CommonCode.StringToCSVCell(date_article), CommonCode.StringToCSVCell(article_title), CommonCode.StringToCSVCell(articleMiddle), CommonCode.StringToCSVCell(url_Img));
Спасибо, теперь работает!
 
  • Спасибо
Реакции: nicanil

Кто просматривает тему: (Всего: 3, Пользователи: 0, Гости: 3)