【问题标题】:Email to CSV C# - String isn't formatting correctly电子邮件到 CSV C# - 字符串格式不正确
【发布时间】:2018-06-05 20:10:59
【问题描述】:

所以我目前正在解析我们从工作中收到的电子邮件,所有这些电子邮件的格式几乎完全相同,并且我正在从所有这些电子邮件中获取我需要的数据,但是我在检索“描述”时遇到了问题,它有多行。我已经尝试从这些字符串中删除“\n”,但它并不总是有效。当我打开 .csv 文件时,格式有时很好,但否则字符串中的这些额外返回会破坏整个事情。

这是我的代码:

    public static void Main(string[] args)
    {
        helper();
        Console.WriteLine("Press any key to exit ... ");
        Console.ReadKey();

    } //end main method

    public static void helper()
    {
        //initiate outlook
        Microsoft.Office.Interop.Outlook.Application app = null;
        Microsoft.Office.Interop.Outlook._NameSpace ns = null;
        Microsoft.Office.Interop.Outlook.MailItem item = null;
        Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;
        Microsoft.Office.Interop.Outlook.MAPIFolder subFolder = null;

        try
        {
            app = new Microsoft.Office.Interop.Outlook.Application();
            ns = app.GetNamespace("MAPI");
            ns.Logon(null, null, false, false);

            inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
            subFolder = inboxFolder.Folders["WorkOrders"]; //folder.Folders[1];
            Console.WriteLine("Folder Name: {0}", subFolder.Name);
            Console.WriteLine("Number of Emails: {0}", subFolder.Items.Count.ToString());
            Console.WriteLine();
            Console.WriteLine("-------------------------");
            Console.WriteLine();

            //Variables for loop
            String sub;
            String date;
            String time;
            String body;
            String desc;
            String storeNumber;
            String workOrderNumber;
            int indexOfDesc;
            int indexOfSp;
            int items = subFolder.Items.Count;

            DataTable dt = new DataTable();
            dt.Columns.Add("Work Order Number");
            dt.Columns.Add("Date");
            dt.Columns.Add("Store Number");
            dt.Columns.Add("Description");
            dt.Rows.Add("Work Order Number", "Date", "Store Number", "Description");
            dt.Rows.Add("", "", "", ""); // just a blank row

            for (int i = 1; i <= items; i++)
            {
                item = (Microsoft.Office.Interop.Outlook.MailItem)subFolder.Items[i];
                sub = item.Subject;
                date = item.SentOn.ToLongDateString();
                body = item.Body;
                desc = "";
                storeNumber = sub.Substring(0, 5);
                workOrderNumber = sub.Substring(sub.Length - 10);
                indexOfDesc = body.IndexOf("Description Overview:");
                indexOfSp = body.IndexOf("Safety Precautions:");
                desc = body.Substring(indexOfDesc, indexOfSp - indexOfDesc);
                desc = desc.Replace("\t", string.Empty);
                desc = desc.Replace("\n", string.Empty);

                // Add row in data table
                dt.Rows.Add(workOrderNumber, date, storeNumber, desc);

                // Process Date
                createCSV(dt);

                // *** Console Output for testing *** //
                Console.WriteLine("Index: {0}", i.ToString());
                Console.WriteLine("Store Number: {0}", sub.Substring(0, 5));
                Console.WriteLine("Work Order Number: # " + workOrderNumber);
                Console.WriteLine("Sent: {0}", date);
                Console.WriteLine(desc);
                Console.WriteLine();
                Console.WriteLine("-------------------------");
                Console.WriteLine();
            }

            PrintTable(dt);
        }
        catch (System.Runtime.InteropServices.COMException ex)
        {
            Console.WriteLine(ex.ToString());
        }
        finally
        {
            ns = null;
            app = null;
            inboxFolder = null;
        } //end finally

    }

    private static void PrintTable(DataTable dt)
    {
        DataTableReader dtReader = dt.CreateDataReader();
        while (dtReader.Read())
        {
            for (int i = 0; i < dtReader.FieldCount; i++)
            {
                Console.Write("{0} = {1} ",
                    dtReader.GetName(i).Trim(),
                    dtReader.GetValue(i).ToString().Trim());
            }
            Console.WriteLine();
        }
        dtReader.Close();
    }

    /**
     * createCSV(DataTable dt) takes each line from data 
     * table and appends it to a csv file created at the var path
     * @param dt - DataTable 
     **/
    public static void createCSV(DataTable dt)
    {
        String path = "C:\\Users\\WORK\\Desktop\\test.csv";
        StringBuilder sb = new StringBuilder();
        foreach(DataRow dr in dt.Rows){
            foreach(DataColumn dc in dt.Columns){
                sb.Append(FormatCSV(dr[dc.ColumnName].ToString()) + ",");
            } // end foreach
            sb.Remove(sb.Length-1,1); //remove comma
            sb.AppendLine();
        } // end foreach
        File.WriteAllText(path, sb.ToString());
    } // end createCSV()

    public static string FormatCSV(string input)
    {
        try
        {
            if (input == null)
                return string.Empty;

            bool containsQuote = false;
            bool containsComma = false;
            int len = input.Length;
            for (int i = 0; i < len && (containsComma == false || containsQuote == false); i++)
            {
                char ch = input[i];
                if (ch == '"')
                    containsQuote = true;
                else if (ch == ',')
                    containsComma = true;
            }

            if (containsQuote && containsComma)
                input = input.Replace("\"", "\"\"");

            if (containsComma)
                return "\"" + input + "\"";
            else
                return input;
        }
        catch
        {
            throw;
        }
    }

} //end class

这是 CSV 文件的截图。请注意,电子邮件中的所有描述都有额外的空格和内容,并且我突出显示了按我想要的方式工作的行:没有额外的空格,只有一行正确的信息。你可以看到回报是如何破坏电子表格的。

因此,我们将不胜感激任何帮助。

【问题讨论】:

  • 我发现最好按照\r\n\r\n的顺序替换。不过,在你的情况下,你只是用一个空字符串替换——也许也只是做 \r 替换。
  • 完美运行!将您的评论添加到答案中,以便我可以更新它。我用空替换了“\r\n”,然后替换了\r,最后替换了\n,它起作用了。非常感谢@TyCobb

标签: c# csv stringbuilder


【解决方案1】:

使用换行符时的一个问题是,有时它不是 Windows 使用的标准 CRLF (\r\n)。有时只是\r,有时只是\n

当您无法控制换行符时,它可以作为一个不错的安全网来替换所有三个字符。

var sub = string.Empty;
var foo = myString.Replace("\r\n", sub).Replace("\r", sub).Replace("\n", sub);

这解决了你有发言权的情况

Some line item\r\n Another line item\n Last line item\r

仅删除 \n 可能在一个应用程序中工作得很好,但另一个显示相同字符串的应用程序可能仍会将其放在新行上。

【讨论】:

    猜你喜欢
    • 2020-04-22
    • 2012-06-21
    • 2018-07-04
    • 1970-01-01
    • 2018-01-07
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    相关资源
    最近更新 更多