Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于列表的复杂CSV文件输出<;订单>;订单收集_C#_Csv - Fatal编程技术网

C# 基于列表的复杂CSV文件输出<;订单>;订单收集

C# 基于列表的复杂CSV文件输出<;订单>;订单收集,c#,csv,C#,Csv,我必须制作这个CSV布局,但有点不确定如何做 我有一个订单类,我必须转换成CSV文件 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;} p

我必须制作这个CSV布局,但有点不确定如何做

我有一个订单类,我必须转换成CSV文件

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;}
}
如果有2项以上,则必须输出:

"orderID", "Created", "Item01", "quantity01", "Item02", "N"
"", "", "Item03", "quantity03", "", "", "Y"
所以上面的顺序有3个项目,注意项目#4的占位符仍然存在,但是只有空的双引号

因此每个字段都是必填项。

我将如何制作这个

到目前为止,我已经:

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(",");
         }

}
StringBuilder sb=新建StringBuilder();
对于(int x=0;x
我想诀窍是找出是否需要继续下一行,然后如果行中的项目少于2个,我就必须填充任何空白点?


(您可以忽略输出中的任何错误字符,我将稍后处理,谢谢)

您的内部循环如下所示:

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")
}
for(i=0;i

您可以展开伪代码。。。csv格式有点不寻常。通常情况下,csv会包含一个项目列表,每行一个(每行中重复一个订单号)。

我发现它有助于将此类问题分解为几种方法,每种方法都易于理解,并且只需完成一小部分工作。然后你可以把它们结合起来解决更大的问题

这里有一些东西可以帮助你开始。它需要更多的错误处理,并且可能需要在生成CSV字段时处理转义特殊字符的逻辑(例如,如果SKU中可能包含逗号或引号)

公共类秩序
{
公共int ID{get;set;}
已创建公共int{get;set;}
公共列表项{get;set;}
}
公共类项目
{
公共字符串Sku{get;set;}
公共整数数量{get;set;}
}
公共类OrderCsvBuilder
{
私有只读StringBuilder m_CsvData=新StringBuilder();
//构造函数接受序列或命令
公共订单CsvBuilder(IEnumerable订单)
{
foreach(订单中的var订单)
书面订单(订单);
}
//以字符串形式返回格式化的CSV数据
公共字符串GetCsvData()
{
返回m_CsvData.ToString();
}
//将单个订单及其行项目写入csv格式
专用无效写订单(订单)
{
WriteCsvFields(false,order.ID,order.Created);
var itemIndex=0;
foreach(order.Items中的变量项)
WriteOrderItem(item,itemIndex++);
}
//将单个订单项写入csv格式
私有void WriteOrderItem(项项,int项索引)
{
//当订单项不是第一项时,写入额外字段
如果(itemIndex>0)
WriteCsvFields(false,string.Empty,string.Empty);
//使用(?:)附加项目是第一项还是附加项的指示符
WriteCsvFields(true、item.Quantity、item.Sku、itemIndex>0?“Y”:“N”);
}
//以csv格式将一系列字段写入文件
私有void WriteCsvFields(bool isLineEnd,params object[]字段)
{
//以CSV格式将每个字段写入StringBuilder
//TODO:需要更好的错误处理和特殊字符转义
foreach(字段中的变量字段)
{
m_CsvData.AppendFormat(“\”{0}\”,“,字段);
}
//如果这是行的最后一项,请修剪额外的尾随空格和逗号
如果(isLineEnd)
m_CsvData.Remove(m_CsvData.Length-2,2);
}
}
公共字符串BuildOrdersCsv(列出订单)
{
StringBuilder sb=新的StringBuilder();
foreach(订单中的订单o)
{
附加(sb,o.ID,o.Created);
对于(int i=0;i<2;i++)
{
如果(i
未经测试,但您获得了jist。在这种形式下,它可能不能完全满足您的需求,但很容易根据您的需求进行调整。不需要所有那些stringbuilder的废话

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);
    }
}
公共类秩序
{
公共int ID{get;set;}
已创建公共int{get;set;}
公共列表项{get;set;}
公共重写字符串ToString()
{
字符串fakeItem=“”;
如果(Items.Count>2)
fakeItem=Environment.NewLine+@“”、“”、“”Y“”;//或任何您想要的内容。
返回string.Join(@“{0},{1},{2},{3}”,
身份证件
已创建==0?“Y”:“N”,
string.Join(“,”,来自Items.Take中的项(2)选择item.ToString()),
伪造);
}
}
公共类项目
{
公共字符串Sku{get;set;}
公共整数数量{get;set;}
公共重写字符串ToString()
{
返回string.Format(@“{0},{1}”,Sku,Quantity);
}
}

吃莫奇金。接受更多的回答。
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")
}
    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);
        }
    }
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("\",");
    }
}
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);
    }
}