সিএসভি এক্সেল ফাইল সি # কীভাবে তৈরি করবেন? [বন্ধ]


132

আমি সিএসভি এক্সেল ফাইল তৈরির জন্য একটি শ্রেণীর সন্ধান করছি।

প্রত্যাশিত বৈশিষ্ট্য:

  • ব্যবহার করা অত্যন্ত সহজ simple
  • কমা এবং উদ্ধৃতিগুলি এড়িয়ে যায় তাই এক্সেল তাদের সূক্ষ্মভাবে পরিচালনা করে
  • টাইমজোন-প্রুফ ফর্ম্যাটে তারিখ এবং তারিখের সময়গুলি রফতানি করে

আপনি কি এর যোগ্য কোন শ্রেণি জানেন?


12
প্রশ্ন অংশে প্রশ্ন পোষণ করা আরও ভাল, এবং তারপরে উত্তর অংশে আপনার নিজের উত্তর পোস্ট করুন। এটি অনুসন্ধানযোগ্য করে তুলতে প্রশ্নে ট্যাগ এবং কীওয়ার্ড যুক্ত করার বিষয়ে নিশ্চিত হন।
চিজো

গুরুত্বপূর্ণ: ক্যারিজ যখন "মান" তে ফিরে আসে তখন আপনারও উদ্ধৃতি যুক্ত করা উচিত।
অ্যালেক্স

ধন্যবাদ @ ক্রিস, একটি পরামর্শ যদি আমি করতে পারি তবে এই কোডটি একটি কীনটফাউন্ড এক্সপ্লেশন ফেলতে পারে, দয়া করে আমার উত্তরটি দেখুন।
জোসেফ

এর সর্বোত্তম উদাহরণ ... তবে আমি কীভাবে একক ফাইলে দুটি টেবিল যুক্ত করতে পারি, তার মানে আমার দুটি সারিগুলির একটি টেবিল রয়েছে এবং অন্য সারণির 10 টি সারি রয়েছে এবং উভয়েরই স্বতন্ত্র কলামের নাম রয়েছে I আমি উপরে এবং পরে দুটি সারি টেবিল যুক্ত করতে চাই দুটি লাইনের ফাঁক আমি দ্বিতীয় সারণি যুক্ত করতে চাই।
ফ্লোকি

উত্তর:


92

আমার প্রয়োজনের প্রতিচ্ছবি ব্যবহার করে আমি কিছুটা আলাদা সংস্করণ লিখেছিলাম। আমাকে সিএসভিতে অবজেক্টের একটি তালিকা রফতানি করতে হয়েছিল। যদি কেউ এটি ভবিষ্যতের জন্য ব্যবহার করতে চায়।

public class CsvExport<T> where T: class
    {
        public List<T> Objects;

        public CsvExport(List<T> objects)
        {
            Objects = objects;
        }

        public string Export()
        {
            return Export(true);
        }

        public string Export(bool includeHeaderLine)
        {

            StringBuilder sb = new StringBuilder();
            //Get properties using reflection.
            IList<PropertyInfo> propertyInfos = typeof(T).GetProperties();

            if (includeHeaderLine)
            {
                //add header line.
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    sb.Append(propertyInfo.Name).Append(",");
                }
                sb.Remove(sb.Length - 1, 1).AppendLine();
            }

            //add value for each property.
            foreach (T obj in Objects)
            {               
                foreach (PropertyInfo propertyInfo in propertyInfos)
                {
                    sb.Append(MakeValueCsvFriendly(propertyInfo.GetValue(obj, null))).Append(",");
                }
                sb.Remove(sb.Length - 1, 1).AppendLine();
            }

            return sb.ToString();
        }

        //export to a file.
        public void ExportToFile(string path)
        {
            File.WriteAllText(path, Export());
        }

        //export as binary data.
        public byte[] ExportToBytes()
        {
            return Encoding.UTF8.GetBytes(Export());
        }

        //get the csv value for field.
        private string MakeValueCsvFriendly(object value)
        {
            if (value == null) return "";
            if (value is Nullable && ((INullable)value).IsNull) return "";

            if (value is DateTime)
            {
                if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
                    return ((DateTime)value).ToString("yyyy-MM-dd");
                return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
            }
            string output = value.ToString();

            if (output.Contains(",") || output.Contains("\""))
                output = '"' + output.Replace("\"", "\"\"") + '"';

            return output;

        }
    }

ব্যবহারের নমুনা: (প্রতিটি মন্তব্য আপডেট)

CsvExport<BusinessObject> csv= new CsvExport<BusinessObject>(GetBusinessObjectList());
Response.Write(csv.Export());

5
এটি আরও এরকম ছিল: তালিকা <বিজনেসঅবজেক্ট> এক্স = নতুন তালিকা <বিজনেসঅবজেক্ট> (); সিএসভিএক্সপোর্ট <বিজনেসঅবজেক্ট> এক্স = নতুন সিএসভিএক্সপোর্ট <বিজনেসঅবজেক্ট> (ইউজারস);
লুকিয়ে আছে

5
আপনার অযোগ্য ইন্টারফেসটি কোথা থেকে এসেছে?
কিলহোফার

এর সর্বোত্তম উদাহরণ ... তবে আমি কীভাবে একক ফাইলে দুটি টেবিল যুক্ত করতে পারি, তার মানে আমার দুটি সারিগুলির একটি টেবিল রয়েছে এবং অন্য সারণির 10 টি সারি রয়েছে এবং উভয়েরই স্বতন্ত্র কলামের নাম রয়েছে I আমি উপরে এবং পরে দুটি সারি টেবিল যুক্ত করতে চাই দুটি লাইনের ফাঁক আমি দ্বিতীয় সারণি যুক্ত করতে চাই।
ফ্লোকি

2
আমি জানি যে আসল পোস্টটি ২০১১ সালের ছিল, সুতরাং আমি নিশ্চিত নই যে এটি আবার ব্যবহার করা .NET সংস্করণে সম্ভব ছিল কিনা। তবে কেন public string Export()পদ্ধতিটি অপসারণ করবেন না এবং অন্য পদ্ধতিটি public string Export(bool includeHeaderLiner = true)(ডিফল্ট প্যারামিটার মান সহ) এ পরিবর্তন করবেন। আবার, আমি নিশ্চিত নই যে ডিফল্ট প্যারামিটারগুলি 2011 এ উপলব্ধ ছিল কিনা তবে বর্তমান কোডটি আমার কাছে কেবলমাত্র প্রচলিত দেখাচ্ছে।
কেভিন ক্রুইজসেন

19

অনুগ্রহ করে আমাকে ক্ষমা করবেন

তবে আমি মনে করি একটি সার্বজনীন ওপেন-সোর্স সংগ্রহস্থল কোড ভাগ করে নেওয়া এবং অবদান, এবং সংশোধন, এবং সংযোজনের মতো আরও ভাল উপায় "আমি এটি স্থির করেছি, আমি এটি স্থির করেছি"

সুতরাং আমি টপিক-স্টার্টারের কোড এবং সমস্ত সংযোজন থেকে একটি সাধারণ গিট-সংগ্রহস্থল তৈরি করেছি:

https://github.com/jitbit/CsvExport

আমি নিজেও বেশ কয়েকটি দরকারী সংশোধন করেছি। প্রত্যেকে পরামর্শ যোগ করতে পারে, এটিকে অবদানের জন্য কাঁটাচামচ ইত্যাদি etc. ইত্যাদি etc. আমাকে আপনার কাঁটাচামচ প্রেরণ করুন যাতে আমি সেগুলি আবার রেপোতে মার্জ করি।

পুনশ্চ. আমি ক্রিসের জন্য সমস্ত কপিরাইট বিজ্ঞপ্তি পোস্ট করেছি। @ ক্রিস আপনি যদি এই ধারণার বিপরীতে থাকেন - আমাকে জানান, আমি এটি হত্যা করব।


11

সিএসভি-ফাইলগুলি পড়তে এবং লেখার জন্য আরও একটি ভাল সমাধান হ'ল ফাইলহেল্পার্স (ওপেন সোর্স)।


এনবি: এক্সেল সমর্থনটি কেবলমাত্র প্রাথমিক পরিস্থিতিগুলির জন্য : বর্তমান বাস্তবায়িত এক্সেল সমর্থনটি কেবলমাত্র প্রাথমিক পরিস্থিতিতে for আপনার যদি কাস্টম বিন্যাস, চার্ট ইত্যাদির প্রয়োজন হয় তবে আপনাকে অবশ্যই একটি কাস্টম কোডের জন্য যেতে হবে। সরাসরি এনপিওআই লাইব্রেরিটি ব্যবহার করার জন্য দৃ strongly়ভাবে প্রস্তাব দেওয়া হয়
এ কে

6

কীভাবে স্ট্রিং ব্যবহার করবেন? সমস্ত ফোরচ লুপের পরিবর্তে জয়েন করবেন?


স্ট্রিং.জাইন শুধুমাত্র স্ট্রিং [] এ কাজ করে, আমি তালিকা <স্ট্রিং> এর কয়েকটি বৈশিষ্ট্য ব্যবহার করছি।
ক্রিস

12
String.Join("," , List<string>)কাজ করে।
ডেমেন্টিক

6

যদি কেউ চান যে আমি এটিকে সংখ্যায় একটি এক্সটেনশন পদ্ধতিতে রূপান্তরিত করেছি:

public static class ListExtensions
{
    public static string ExportAsCSV<T>(this IEnumerable<T> listToExport, bool includeHeaderLine, string delimeter)
    {
        StringBuilder sb = new StringBuilder();

        IList<PropertyInfo> propertyInfos = typeof(T).GetProperties();

        if (includeHeaderLine)
        {
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                sb.Append(propertyInfo.Name).Append(",");
            }
            sb.Remove(sb.Length - 1, 1).AppendLine();
        }

        foreach (T obj in listToExport)
        {
            T localObject = obj;

            var line = String.Join(delimeter, propertyInfos.Select(x => SanitizeValuesForCSV(x.GetValue(localObject, null), delimeter)));

            sb.AppendLine(line);
        }

        return sb.ToString();
    }

    private static string SanitizeValuesForCSV(object value, string delimeter)
    {
        string output;

        if (value == null) return "";

        if (value is DateTime)
        {
            output = ((DateTime)value).ToLongDateString();
        }
        else
        {
            output = value.ToString();                
        }

        if (output.Contains(delimeter) || output.Contains("\""))
            output = '"' + output.Replace("\"", "\"\"") + '"';

        output = output.Replace("\n", " ");
        output = output.Replace("\r", "");

        return output;
    }
}

5

এই ক্লাসে দুর্দান্ত কাজ। সহজ এবং ব্যবহার সহজ। আমি রফতানির প্রথম সারিতে একটি শিরোনাম অন্তর্ভুক্ত করতে ক্লাসটি সংশোধন করেছি; ভেবেছি আমি ভাগ করে নেব:

ব্যবহার করুন:

CsvExport myExport = new CsvExport();
myExport.addTitle = String.Format("Name: {0},{1}", lastName, firstName));

শ্রেণী:

public class CsvExport
{
    List<string> fields = new List<string>();

    public string addTitle { get; set; } // string for the first row of the export

    List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
    Dictionary<string, object> currentRow
    {
        get
        {
            return rows[rows.Count - 1];
        }
    }

    public object this[string field]
    {
        set
        {
            if (!fields.Contains(field)) fields.Add(field);
            currentRow[field] = value;
        }
    }

    public void AddRow()
    {
        rows.Add(new Dictionary<string, object>());
    }

    string MakeValueCsvFriendly(object value)
    {
        if (value == null) return "";
        if (value is Nullable && ((INullable)value).IsNull) return "";
        if (value is DateTime)
        {
            if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
                return ((DateTime)value).ToString("yyyy-MM-dd");
            return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
        }
        string output = value.ToString();
        if (output.Contains(",") || output.Contains("\""))
            output = '"' + output.Replace("\"", "\"\"") + '"';
        return output;

    }

    public string Export()
    {
        StringBuilder sb = new StringBuilder();

        // if there is a title
        if (!string.IsNullOrEmpty(addTitle))
        {
            // escape chars that would otherwise break the row / export
            char[] csvTokens = new[] { '\"', ',', '\n', '\r' };

            if (addTitle.IndexOfAny(csvTokens) >= 0)
            {
                addTitle = "\"" + addTitle.Replace("\"", "\"\"") + "\"";
            }
            sb.Append(addTitle).Append(",");
            sb.AppendLine();
        }


        // The header
        foreach (string field in fields)
        sb.Append(field).Append(",");
        sb.AppendLine();

        // The rows
        foreach (Dictionary<string, object> row in rows)
        {
            foreach (string field in fields)
                sb.Append(MakeValueCsvFriendly(row[field])).Append(",");
            sb.AppendLine();
        }

        return sb.ToString();
    }

    public void ExportToFile(string path)
    {
        File.WriteAllText(path, Export());
    }

    public byte[] ExportToBytes()
    {
        return Encoding.UTF8.GetBytes(Export());
    }
}


3

আমি এক্সপোর্টটোস্ট্রিম যুক্ত করেছি যাতে সিএসভিকে প্রথমে হার্ড ড্রাইভে সংরক্ষণ করতে হবে না।

public Stream ExportToStream()
{
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(Export(true));
    writer.Flush();
    stream.Position = 0;
    return stream;
}

3

আমি যোগ করেছি

public void ExportToFile(string path, DataTable tabela)
{

     DataColumnCollection colunas = tabela.Columns;

     foreach (DataRow linha in tabela.Rows)
     {

           this.AddRow();

           foreach (DataColumn coluna in colunas)

           {

               this[coluna.ColumnName] = linha[coluna];

           }

      }
      this.ExportToFile(path);

}

পূর্ববর্তী কোড পুরানো .NET সংস্করণগুলির সাথে কাজ করে না। ফ্রেমওয়ার্কের 3.5 সংস্করণের জন্য এই অন্যান্য সংস্করণটি ব্যবহার করুন:

        public void ExportToFile(string path)
    {
        bool abort = false;
        bool exists = false;
        do
        {
            exists = File.Exists(path);
            if (!exists)
            {
                if( !Convert.ToBoolean( File.CreateText(path) ) )
                        abort = true;
            }
        } while (!exists || abort);

        if (!abort)
        {
            //File.OpenWrite(path);
            using (StreamWriter w = File.AppendText(path))
            {
                w.WriteLine("hello");
            }

        }

        //File.WriteAllText(path, Export());
    }

2

ওটার জন্য অসংখ্য ধন্যবাদ! আমি ক্লাসটি এতে পরিবর্তন করেছি:

  • কোডটিতে হার্ডকোডের পরিবর্তে একটি পরিবর্তনশীল ডিলিমিটার ব্যবহার করুন
  • সমস্ত নতুন লাইনে (\ n \ r \ n \ r) প্রতিস্থাপন করা হচ্ছে MakeValueCsvFriendly

কোড:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.SqlTypes;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

    public class CsvExport
    {

        public char delim = ';';
        /// <summary>
        /// To keep the ordered list of column names
        /// </summary>
        List<string> fields = new List<string>();

        /// <summary>
        /// The list of rows
        /// </summary>
        List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();

        /// <summary>
        /// The current row
        /// </summary>
        Dictionary<string, object> currentRow { get { return rows[rows.Count - 1]; } }

        /// <summary>
        /// Set a value on this column
        /// </summary>
        public object this[string field]
        {
            set
            {
                // Keep track of the field names, because the dictionary loses the ordering
                if (!fields.Contains(field)) fields.Add(field);
                currentRow[field] = value;
            }
        }

        /// <summary>
        /// Call this before setting any fields on a row
        /// </summary>
        public void AddRow()
        {
            rows.Add(new Dictionary<string, object>());
        }

        /// <summary>
        /// Converts a value to how it should output in a csv file
        /// If it has a comma, it needs surrounding with double quotes
        /// Eg Sydney, Australia -> "Sydney, Australia"
        /// Also if it contains any double quotes ("), then they need to be replaced with quad quotes[sic] ("")
        /// Eg "Dangerous Dan" McGrew -> """Dangerous Dan"" McGrew"
        /// </summary>
        string MakeValueCsvFriendly(object value)
        {
            if (value == null) return "";
            if (value is INullable && ((INullable)value).IsNull) return "";
            if (value is DateTime)
            {
                if (((DateTime)value).TimeOfDay.TotalSeconds == 0)
                    return ((DateTime)value).ToString("yyyy-MM-dd");
                return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
            }
            string output = value.ToString();
            if (output.Contains(delim) || output.Contains("\""))
                output = '"' + output.Replace("\"", "\"\"") + '"';
            if (Regex.IsMatch(output,  @"(?:\r\n|\n|\r)"))
                output = string.Join(" ", Regex.Split(output, @"(?:\r\n|\n|\r)"));
            return output;
        }

        /// <summary>
        /// Output all rows as a CSV returning a string
        /// </summary>
        public string Export()
        {
            StringBuilder sb = new StringBuilder();

            // The header
            foreach (string field in fields)
                sb.Append(field).Append(delim);
            sb.AppendLine();

            // The rows
            foreach (Dictionary<string, object> row in rows)
            {
                foreach (string field in fields)
                    sb.Append(MakeValueCsvFriendly(row[field])).Append(delim);
                sb.AppendLine();
            }

            return sb.ToString();
        }

        /// <summary>
        /// Exports to a file
        /// </summary>
        public void ExportToFile(string path)
        {
            File.WriteAllText(path, Export());
        }

        /// <summary>
        /// Exports as raw UTF8 bytes
        /// </summary>
        public byte[] ExportToBytes()
        {
            return Encoding.UTF8.GetBytes(Export());

        }

    }


1

মূল শ্রেণীর একটি সমস্যা আছে এবং এটি হ'ল যদি আপনি একটি নতুন কলাম যুক্ত করতে চান তবে আপনি রফতানি পদ্ধতিতে কী-নটফাউন্ডএক্সসেপশন পাবেন। উদাহরণ স্বরূপ:

static void Main(string[] args)
{
    var export = new CsvExport();

    export.AddRow();
    export["Region"] = "New York, USA";
    export["Sales"] = 100000;
    export["Date Opened"] = new DateTime(2003, 12, 31);

    export.AddRow();
    export["Region"] = "Sydney \"in\" Australia";
    export["Sales"] = 50000;
    export["Date Opened"] = new DateTime(2005, 1, 1, 9, 30, 0);
    export["Balance"] = 3.45f;  //Exception is throwed for this new column

    export.ExportToFile("Somefile.csv");
}

এটি সমাধান করার জন্য, এবং প্রতিবিম্বটি ব্যবহার করার জন্য @ কীবোর্ডকোবয় ধারণাটি ব্যবহার করে, আমি কোডটি সংশোধন করেছিলাম যাতে একই কলামগুলিতে নেই এমন সারি যুক্ত করার অনুমতি দেওয়া হয়। আপনি বেনাম শ্রেণীর উদাহরণ ব্যবহার করতে পারেন। উদাহরণ স্বরূপ:

static void Main(string[] args)
{
    var export = new CsvExporter();

    export.AddRow(new {A = 12, B = "Empty"});
    export.AddRow(new {A = 34.5f, D = false});

    export.ExportToFile("File.csv");
}

আপনি সোর্স কোডটি এখানে সিএসভিএক্সপোর্টার ডাউনলোড করতে পারেন । বিনামূল্যে ব্যবহার করুন এবং সংশোধন করুন।

এখন, আপনি যে সমস্ত সারি লিখতে চান তা যদি একই শ্রেণীর হয় তবে আমি জেনেরিক ক্লাসটি তৈরি করেছি CSvWriter.cs , যা আরও ভাল পারফরম্যান্সের র্যাম ব্যবহার করে এবং বড় ফাইলগুলি লেখার জন্য আদর্শ lus । ব্যবহারের একটি উদাহরণ:

class Program
{
    static void Main(string[] args)
    {
        var writer = new CsvWriter<Person>("Persons.csv");

        writer.AddFormatter<DateTime>(d => d.ToString("MM/dd/yyyy"));

        writer.WriteHeaders();
        writer.WriteRows(GetPersons());

        writer.Flush();
        writer.Close();
    }

    private static IEnumerable<Person> GetPersons()
    {
        yield return new Person
            {
                FirstName = "Jhon", 
                LastName = "Doe", 
                Sex = 'M'
            };

        yield return new Person
            {
                FirstName = "Jhane", 
                LastName = "Doe",
                Sex = 'F',
                BirthDate = DateTime.Now
            };
        }
    }


    class Person
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public char Sex  { get; set; }

        public DateTime BirthDate { get; set; }
    }

0

এটি করার জন্য আপনার কেবলমাত্র 1 টি ফাংশন প্রয়োজন। কেবলমাত্র আপনার সমাধান এক্সপ্লোরারটিতে একটি ফোল্ডার তৈরি করতে হবে এবং সেখানে সিএসভি ফাইল সংরক্ষণ করতে হবে এবং তারপরে সেই ফাইলটি ব্যবহারকারীকে রফতানি করতে হবে।

আমার ক্ষেত্রে যেমন আমার ফোল্ডার ডাউনলোড আছে। প্রথমে আমি আমার সমস্ত সামগ্রী সেই ডিরেক্টরিতে রফতানি করি এবং তারপরে এটি ব্যবহারকারীর কাছে রফতানি করি। প্রতিক্রিয়া.এন্ড হ্যান্ডলিংয়ের জন্য, আমি থ্রেডআবার্ট এক্সসেপশন ব্যবহার করেছি। সুতরাং এটি আমার সমাধানে 100% খাঁটি এবং কার্যকরী ফাংশন।

protected void lnkExport_OnClick(object sender, EventArgs e)
{

    string filename = strFileName = "Export.csv";

    DataTable dt = obj.GetData();  

// call the content and load it into the datatable

    strFileName = Server.MapPath("Downloads") + "\\" + strFileName;

// creating a file in the downloads folder in your solution explorer

    TextWriter tw = new StreamWriter(strFileName);

// using the built in class textwriter for writing your content in the exporting file

    string strData = "Username,Password,City";

// above line is the header for your exported file. So add headings for your coloumns in excel(.csv) file and seperate them with ","

    strData += Environment.NewLine;

// setting the environment to the new line

    foreach (DataRow dr in dt.Rows)
    {
       strData += dr["Username"].ToString() + "," + dr["Password"].ToString() + "," +      dr["City"].ToString();
       strData += Environment.NewLine;
    }

// everytime when loop execute, it adds a line into the file
    tw.Write(strData);

// writing the contents in file
    tw.Close();

// closing the file
    Response.Redirect("Downloads/" + filename);

// exporting the file to the user as a popup to save as....
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.