支付宝账单是zip压缩文件流,里面包含了两个.csv文件。

1.请求支付宝账单下载链接,获取到zip文件流。

 var httpClient = _clientFactory.CreateClient();
var stream = await httpClient.GetStreamAsync(response.BillDownloadUrl);//获取流
string extractPath = $@"{_hostingEnvironment.ContentRootPath}/file/alipay";//需要解压到的文件夹路径
if (!extractPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
extractPath += Path.DirectorySeparatorChar;
//获取zip内容。GB2312需要在 Program Main方法中注册: System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read, true, System.Text.Encoding.GetEncoding("GB2312")))
{
foreach (var item in archive.Entries)
{
string destinationPath = Path.GetFullPath(Path.Combine(extractPath, item.FullName));
item.ExtractToFile(destinationPath, true);//解压到指定文件夹,true代表覆盖原有的文件
}
}

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上安装)

 //这里直接读取zip文件中的流item.Open(),亦可以读取文件。具体用法可参考CsvHelper官方文档
using (TextReader reader = new StreamReader(item.Open(), System.Text.Encoding.GetEncoding("GB2312")))
{
using (var csv = new CsvReader(reader))
{
csv.Configuration.RegisterClassMap<AliPayBillMap>();//AliPayBillMap是自定义的map,在下文贴出
var aliPayBills = new List<Model.AliPayBill>();
var isHeader = true;
while (csv.Read())
{
if (!csv.GetField().StartsWith('#'))//过滤#开头的行
{
if (isHeader)//读取表头
{
csv.ReadHeader();
isHeader = false;
continue;
}
aliPayBills.Add(csv.GetRecord<Model.AliPayBill>());//映射
}
}
}
}

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,请做相应的处理。

NetCore利用CsvHelper解析支付宝对账单的更多相关文章

  1. Android利用Jsoup解析html 开发网站客户端小记。

    这些天业余时间比较多,闲来无事,想起了以前看过开发任意网站客户端的一篇文章,就是利用jsoup解析网站网页,通过标签获取想要的内容.好了废话不多说,用到的工具为 jsoup-1.7.2.jar包,具体 ...

  2. 使用XML序列化器生成XML文件和利用pull解析XML文件

    首先,指定XML格式,我指定的XML格式如下: <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <message&g ...

  3. 利用XPath解析带有xmlns的XML文件

    在.net中,编写读取xml 的程序中提示"未将对象引用设置到对象的实例",当时一看觉得有点奇怪.为什么在读取xml数据的时候也要实例化一个对象.google了才知道,xml文件中 ...

  4. java中利用dom4j解析XML文件

    官网下载Dom4j地址:https://dom4j.github.io/ 注意:使用Dom4j开发,需下载dom4j相应的jar文件 题目:后台利用dom4j解析student.xml文件,并返回Li ...

  5. IOS开发---菜鸟学习之路--(二十一)-利用正则表达式解析URL获取其中的参数

    因为项目需要解析URL当中参数的部分,在网上搜索了一下都没有相关的资料. 然后就自己写了一个 其实我就是通过正则表达式来处理URL 进行解析的 好了直接上代码吧 也是非常的简单,大家拷贝过去就可以使用 ...

  6. Xml学习笔记(3)利用递归解析Xml文档添加到TreeView中

    利用递归解析Xml文档添加到TreeView中 private void Form1_Load(object sender, EventArgs e) { XmlDocument doc = new ...

  7. 在java项目中怎样利用Dom4j解析XML文件获取数据

    在曾经的学习.net时常常会遇到利用配置文件来解决项目中一些须要常常变换的数据.比方数据库的连接字符串儿等.这个时候在读取配置文件的时候.我们一般会用到一个雷configuration,通过这个类来进 ...

  8. 利用 nodejs 解析 m3u8 格式文件,并下 ts 合并为 mp4

    利用 nodejs 解析 m3u8 格式文件,并下 ts 合并为 mp4 以前看视频的时候,直接找到 video标签,查看视频地址,然后下载下来.. 后来发现,好多 video 标签打开元素审查,如下 ...

  9. Apache Common-collection 反序列化利用链解析--TransformedMap链

    Apache Common-collection 反序列化利用链解析 TransformedMap链 参考Java反序列化漏洞分析 - ssooking - 博客园 (cnblogs.com) poc ...

随机推荐

  1. web前端架构师学习流程

    JavaScript 开发(高级) 系统知识 1.1ECMAScript标准的发展过程,ES6语言对JavaScript的改进: 1.2ES6中语法层面的新特性(let.const.参数扩展.模块化等 ...

  2. Android中Parcelable的原理和使用方法

    Parcelable的简单介绍 介绍Parcelable不得不先提一下Serializable接口,Serializable是Java为我们提供的一个标准化的序列化接口,那什么是序列化呢? 进行And ...

  3. bzoj 1176 cdq分治套树状数组

    题面: 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Inp ...

  4. memcache、mongodb、redis的对比区别

    >>Memcached Memcached的优点:Memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key.value的字节大小以及服务器硬件性能,日常环境 ...

  5. mongoose 与 mylab 的使用 (1)

    1.引入mongoose  模块 const mongoose = require('mongoose'); 2.连接数据库 //连接数据库 mongoose.connect( db, {useNew ...

  6. Foobar 2000增加APE播放支持的方法

    这里说明一下APE,它是一种常用的无损音乐的存储格式,通常会有将原始音乐光盘数字化后存储的APE文件搭配一个CUE文件使用.这个APE存储了音乐的原始数据,而CUE文件则是一个索引文件,用来标记音乐光 ...

  7. python 常用技巧 — 数组 (array)

    目录: 1. 数组每一行除以这一行的总数(numpy divide row by row sum) 2. 数组每一行或者每一列求平均 (python average array columns or ...

  8. 【leetcode】207. Course Schedule

    题目如下: There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have ...

  9. leetcode-166周赛-5280-用户分组

    题目描述: 自己的提交: class Solution: def groupThePeople(self, groupSizes: List[int]) -> List[List[int]]: ...

  10. Python--模块之time、random、os、hashlib

    今天开始模块. 首先补充 __init__.py       在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录,假如子目录中 ...