vanskelig CSV fil produksjon basert på en liste <Bestill> ordrer samling

stemmer
0

Jeg har til å produsere denne CSV layout, men litt usikker på hvordan du gjør det.

Jeg har en Order klasse at jeg må konvertere til en CSV-fil.

public class Order
{
       public int ID {get; set;}
       public int Created {get;set;}
       public List<Item> Items {get;set;}
}
public class Item
{
        public string Sku {get;set;}
        public int Quantity {get;set;}
}

Så hver rad representerer en ordre. Hvis en ordre har mer enn 2 elementer i det, vil jeg ha for å fortsette til neste linje forlate alt tomt bortsett fra sku, kvantitet og en specifical felt.

Det siste feltet vil være Y hvis dens fortsatte fra den foregående linje, N ellers.

Så jeg har:

List<Order> orders = Db.GetOrders();

Så et eksempel produksjon av CSV vil være:

orderID, Created, Item01, quantity01, Item02, N

hvis det er mer enn 2 elementer, må det utgang:

orderID, Created, Item01, quantity01, Item02, N
, , Item03, quantity03, , , Y

Så nevnte rekkefølge hadde 3 elementer, legge merke til hvordan plassholder for Varenummer 4 er fortsatt til stede, men bare tomt anførselstegn.

Så hver feltet er obligatorisk.

Hvordan skulle jeg produsere dette?

Så langt jeg har:

StringBuilder sb = new StringBuilder();

for(int x = 0; x < orders.Count; x++)
{
         Order o = orders[x];

         if(x % 2 = 0)
         {
           sb.Append(o.ID).Append(,);
           sb.Append(o.Created).Append(,);
         }

}

Trikset jeg antar er å finne ut om jeg trenger å fortsette til neste linje, og så må jeg fylle noen tomme flekker hvis jeg har mindre enn 2 elementer i rad?

(Du kan ignorere noen dårlige tegn i utgang, vil jeg forholde vilje som senere takk)

Publisert på 29/12/2009 klokken 23:45
kilden bruker
På andre språk...                            


4 svar

stemmer
0

din indre sløyfe ser omtrent slik ut:

for (i = 0; i < items.Count; ++i) {
  sb.Append(sku)
  sb.Append(qty)
  if (i % 2 == 1) {
    if (i == items.Count - 1) {
      sb.Append("N\n")
    } else {
      sb.Append("Y\n" "" "");
    }
  }
}
if (items.Count == 0) {
  sb.Append("" "" "" "" "N")
}
if (items.Count % 2 == 1) {
  sb.Append("" "" "N")
}

du kan utvide pseudo ... CSV-formatet er litt uvanlig. typisk en csv ville inneholde en liste over elementer, en per linje (bestillingsnummer gjentas i hver).

Svarte 30/12/2009 kl. 00:08
kilden bruker

stemmer
0

Jeg synes det hjelper å dekomponere problemer som dette i flere metoder som hver er enkle å forstå og gjøre en liten del av jobben. Deretter kan du kombinere dem til å løse større problem.

Her er noe for å hjelpe deg i gang. Det er behov for mer feilhåndtering og sannsynligvis trenger logikk for å håndtere rømmer spesialtegn ved generering av CSV felt (hvis SKU kan ha komma eller sitater i det, for eksempel).

    public class Order
    {
        public int ID { get; set; }
        public int Created { get; set; }
        public List<Item> Items { get; set; }
    }
    public class Item
    {
        public string Sku { get; set; }
        public int Quantity { get; set; }
    }

    public class OrderCsvBuilder
    {
        private readonly StringBuilder m_CsvData = new StringBuilder();

        // constructor accepts a sequence or Orders
        public OrderCsvBuilder(IEnumerable<Order> orders)
        {
            foreach (var order in orders)
                WriteOrder(order);
        }

        // returns the formatted CSV data as a string
        public string GetCsvData()
        {
            return m_CsvData.ToString();
        }

        // writes a single order and its line items to csv format
        private void WriteOrder( Order order )
        {
            WriteCsvFields( false, order.ID, order.Created );
            var itemIndex = 0;
            foreach( var item in order.Items )
                WriteOrderItem( item, itemIndex++ );
        }

        // writes a single order item to csv format
        private void WriteOrderItem( Item item, int itemIndex )
        {
            // write the extra fields when the order item is not the first item
            if( itemIndex > 0 )
                WriteCsvFields( false, string.Empty, string.Empty );
            // use (?:) to append indicator of whether item is first or additional
            WriteCsvFields( true, item.Quantity, item.Sku, itemIndex > 0 ? "Y" : "N" );
        }

        // writes a series of fields to the file in csv form
        private void WriteCsvFields( bool isLineEnd, params object[] fields )
        {
            // write each field to the StringBuilder in CSV format
            // TODO: Need better error handling and escaping of special characters
            foreach( var field in fields )
            {
                m_CsvData.AppendFormat("\"{0}\", ", field);
            }
            // trim extra trailing space and comma if this is the last item of a line
            if( isLineEnd )
                m_CsvData.Remove(m_CsvData.Length - 2, 2);
        }
    }
Svarte 30/12/2009 kl. 00:21
kilden bruker

stemmer
0
public string BuildOrdersCsv(List<Order> orders)
{
    StringBuilder sb = new StringBuilder();

    foreach (Order o in orders)
    {
        Append(sb, o.ID, o.Created);
        for (int i = 0; i < 2; i++)
        {
            if (i < o.Items.Count)
                Append(sb, o.Items[i].Sku, o.Items[i].Quantity);
            else
                Append(sb, "", "");
        }
        sb.AppendLine("\"N\"");

        for (int i = 2; i < o.Items.Count; i++)
        {
            Append(sb, "", "", o.Items[i].Sku, o.Items[i].Quantity, "", "");
            sb.AppendLine("\"Y\"");
        }
    }

    return sb.ToString();
}

private void Append(StringBuilder sb, params object[] items)
{
    foreach (object item in items)
    {
        sb.Append("\"").Append(item).Append("\",");
    }
}
Svarte 30/12/2009 kl. 00:29
kilden bruker

stemmer
0

Utestet, men du får jist. Det kan ikke gjøre akkurat hva du vil i dette skjemaet, men lett å justere til hva du vil. Ikke behov for alle som Stringbuilder crap.

public class Order
{
    public int ID { get; set; }
    public int Created { get; set; }
    public List<Item> Items { get; set; }
    public override string ToString()
    {
        string fakeItem = "";
        if(Items.Count > 2) 
            fakeItem = Environment.NewLine + @""""", """", ""Y"" "; // or whatever you want.
        return string.Join(@"{0}, {1}, {2}, {3}", 
            ID, 
            Created == 0 ? "Y" : "N", 
            string.Join(", ", from item in Items.Take(2) select item.ToString()),
            fakeItem);
    }
}
public class Item
{
    public string Sku { get; set; }
    public int Quantity { get; set; }
    public override string ToString()
    {
        return string.Format(@"{0}, {1}", Sku, Quantity);
    }
}
Svarte 07/07/2014 kl. 10:28
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more