支付宝账单是zip压缩文件流,里面包含了两个.csv文件。
1.请求支付宝账单下载链接,获取到zip文件流。
1 var httpClient = _clientFactory.CreateClient(); 2 var stream = await httpClient.GetStreamAsync(response.BillDownloadUrl);//获取流 3 string extractPath = $@"{_hostingEnvironment.ContentRootPath}/file/alipay";//需要解压到的文件夹路径 4 if (!extractPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) 5 extractPath += Path.DirectorySeparatorChar; 6 //获取zip内容。GB2312需要在 Program Main方法中注册: System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); 7 using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read, true, System.Text.Encoding.GetEncoding("GB2312"))) 8 { 9 foreach (var item in archive.Entries) 10 { 11 string destinationPath = Path.GetFullPath(Path.Combine(extractPath, item.FullName)); 12 item.ExtractToFile(destinationPath, true);//解压到指定文件夹,true代表覆盖原有的文件 13 } 14 } 15
2.解析csv文件
支付宝对账单中,其中xxx_业务明细.csv格式如下:
#支付宝业务明细查询 #账号:[xxxxxxxxx] #起始日期:[2019年08月01日 00:00:00] 终止日期:[2019年08月02日 00:00:00] #-----------------------------------------业务明细列表---------------------------------------- 支付宝交易号,商户订单号,业务类型,商品名称,创建时间,完成时间,门店编号,门店名称,操作员,终端号,对方账户,订单金额(元),商家实收(元),支付宝红包(元),集分宝(元),支付宝优惠(元),商家优惠(元),券核销金额(元),券名称,商家红包消费金额(元),卡消费金额(元),退款批次号/请求号,服务费(元),分润(元),备注 xxxxxxx ,xxxxxxx ,交易 ,1,2019-08-01 18:50:14,2019-08-01 18:50:18, , , , ,*渠(131****81) ,1.00,1.00,0.00,0.00,0.00,0.00,0.00,,0.00 ,0.00, ,-0.01,0.00,1 xxxxxxx ,xxxxxxx ,退款 ,1,2019-08-01 18:50:14,2019-08-01 19:09:31, , , ,1 ,*渠(131****81) ,-1.00,-1.00,0.00,0.00,0.00,0.00,0.00,,0.00 ,0.00,xxxxxxx ,0.01,0.00,1 #-----------------------------------------业务明细列表结束------------------------------------ #交易合计:4笔,商家实收共1.03元,商家优惠共0.00元 #退款合计:1笔,商家实收退款共-1.00元,商家优惠退款共0.00元 #导出时间:[2019年08月02日 05:28:48]
发现其说明的行都是以 # 开头,可按此过滤
使用CsvHelper读取文件:(CsvHelper需要在nuget上安装)
1 //这里直接读取zip文件中的流item.Open(),亦可以读取文件。具体用法可参考CsvHelper官方文档 2 using (TextReader reader = new StreamReader(item.Open(), System.Text.Encoding.GetEncoding("GB2312"))) 3 { 4 using (var csv = new CsvReader(reader)) 5 { 6 csv.Configuration.RegisterClassMap<AliPayBillMap>();//AliPayBillMap是自定义的map,在下文贴出 7 var aliPayBills = new List<Model.AliPayBill>(); 8 var isHeader = true; 9 while (csv.Read()) 10 { 11 if (!csv.GetField(0).StartsWith(‘#‘))//过滤#开头的行 12 { 13 if (isHeader)//读取表头 14 { 15 csv.ReadHeader(); 16 isHeader = false; 17 continue; 18 } 19 aliPayBills.Add(csv.GetRecord<Model.AliPayBill>());//映射 20 } 21 } 22 } 23 }
csv文件的表头跟属性的mapper关系,CsvHelper提供了多种方法。可以根据表头index,也可以根据表头列名。这里采用列名:
public class AliPayBill { /// <summary> /// 支付宝交易号 /// </summary> public string TradeNo { get; set; } /// <summary> /// 商户订单号 /// </summary> public string OrderNo { set; get; } }
public class AliPayBillMap : ClassMap<AliPayBill> { public AliPayBillMap() { Map(x => x.TradeNo).Name("支付宝交易号"); Map(x => x.OrderNo).Name("商户订单号"); //.....这里只举例两个属性。 } }
注意:获取到的数据,可能包含\t,请做相应的处理。
原文:https://www.cnblogs.com/realpht/p/11307869.html