跳至主要内容

实战 之 spfwssflbm.xml2xlsx(用csv过渡)


Navicat工具实现

可以用Navicat连上sqlite数据库,导入spfwssflbm.xml到sqlite3数据库里面再导出表格


代码实现

直接解析gbk编码的xml文件
tree = ET.parse('spfwssflbm.xml')
root = tree.getroot()
需要
1、将C:\Program Files (x86)\开票软件\税号.分机号\Bin下的商品服务税收分类编码spfwssflbm.xml文件放到当前终端下,并用记事本打开另存为utf-8格式
2、首行<?xml version="1.0" encoding="gbk"?>中的编码gbk改为utf-8,不然xml.etree.ElementTree无法解析中文报错

spfwssflbm.xml


参考资料
http://blog.appliedinformaticsinc.com/how-to-parse-and-convert-xml-to-csv-using-python/
https://docs.python.org/3/library/xml.etree.elementtree.html
https://python3-cookbook.readthedocs.io/zh_CN/latest/c06/p03_parse_simple_xml_data.html

环境
python3.7.2
jupyter notebook、vscode、PyCharm、Thonny上验证通过


excel to dict
  1. import pandas as pd
  2. my_dic = pd.read_excel(r'C:\Users\DZL\Desktop\spfwssflbm.xlsx', index_col=0).to_dict()
  3. print(my_dic)


代码如下


  1. import xml.etree.ElementTree as ET
  2. import csv
  3. import pandas as pd
  4.  
  5. # 字段中英文对照
  6. dic = {'BB''版本',
  7.        'QYSJ''启用时间',
  8.        'GDQJZSJ''过渡期截止时间',
  9.        'SPBM''商品编码',
  10.        'SPMC''商品名称',
  11.        'SPBMJC''商品编码简称',
  12.        'SM''说明',
  13.        'ZZSSL''增值税税率',
  14.        'GJZ''关键字',
  15.        'HZX''是否汇总项',
  16.        'KYZT''可用状态',
  17.        'ZZSTSGL''增值税特殊管理',
  18.        'ZZSZCYJ''增值税政策依据',
  19.        'ZZSTSNRDM''增值税特殊内容代码',
  20.        'XFSGL''消费税管理',
  21.        'XFSZCYJ''消费税政策依据',
  22.        'XFSTSNRDM''消费税特殊内容代码',
  23.        'TJJBM''统计局编码',
  24.        'HGJCKSPPM''海关进出口商品品目',
  25.        'PID''PID',
  26.        'GXSJ''更新时间'}
  27.  
  28. # tree = ET.parse('spfwssflbm.xml')
  29. # root = tree.getroot()
  30. # 避免直接解析gbk编码的xml文件报错
  31. with open('spfwssflbm.xml', 'rb') as f:
  32.    root = ET.fromstring(f.read().decode('gbk', 'ignore'))
  33.  
  34. # newline=''防止生成空白行, encoding='utf_8_sig'自动转码
  35. with open('spfwssflbm.csv', 'w', newline='', encoding='utf_8_sig') as flbm_data:
  36.     csvwriter = csv.writer(flbm_data)
  37.     # 添加标题行
  38.     flbm_head = []
  39.     for i in dic.values():
  40.         flbm_head.append(i)    
  41.     csvwriter.writerow(flbm_head)
  42.  
  43.     for bmxx in root.findall('body/BMXX'):
  44.         # 添加内容
  45.         flbm_body = []
  46.         for j in dic.keys():
  47.             flbm_body.append(bmxx.find(j).text)
  48.         csvwriter.writerow(flbm_body)
  49.  
  50. df = pd.read_csv('spfwssflbm.csv', index_col=False)
  51. # 避免版本丢失小数点, 商品编码、PID变成科学计数法
  52. df['版本'] = df['版本'].apply(lambda x: '{:.1f}'.format(float(x)))
  53. df['商品编码'] = df['商品编码'].apply(lambda x: '{:d}'.format(int(x)))
  54. df['PID'] = df['PID'].apply(lambda x: '{:d}'.format(int(x)))
  55.  
  56. df.to_excel('spfwssflbm.xlsx',index=False)


import xml.etree.ElementTree as ET
import csv

tree = ET.parse('spfwssflbm.xml')
root = tree.getroot()

#open() 函数用于打开一个文件,创建一个 file 对象
#Flbm_data = open('spfwssflbm.csv', 'w')
#newline=''防止生成空白行,encoding='utf_8_sig'自动转码
with open('spfwssflbm.csv', 'w', newline='', encoding='utf_8_sig') as Flbm_data:
    csvwriter = csv.writer(Flbm_data)
    flbm_head = []
    count = 0

    for bmxx in root.findall('body/BMXX'):
        flbm = []     
        if count == 0:
         
            #字符串相加,组成表头
            spbm = '商品编码(' + bmxx.find('SPBM').tag + ')'
            flbm_head.append(spbm)

            bb = '版本号(' + bmxx.find('BB').tag + ')'
            flbm_head.append(bb)

            spmc = '商品名称(' + bmxx.find('SPMC').tag + ')'
            flbm_head.append(spmc)

            spbmjc = '商品编码简称(' + bmxx.find('SPBMJC').tag + ')'
            flbm_head.append(spbmjc)

            kyzt = '可用状态(' + bmxx.find('KYZT').tag + ')'
            flbm_head.append(kyzt)

            hzx = '是否大类(' + bmxx.find('HZX').tag + ')'
            flbm_head.append(hzx)

            zzssl = '税率(' + bmxx.find('ZZSSL').tag + ')'
            flbm_head.append(zzssl)

            gjz = '关键字(' + bmxx.find('GJZ').tag + ')'
            flbm_head.append(gjz)

            sm = '说明(' + bmxx.find('SM').tag + ')'
            flbm_head.append(sm)
         
            csvwriter.writerow(flbm_head)
            count = count + 1
     
        spbm = bmxx.find('SPBM').text
        flbm.append(spbm)

        bb = bmxx.find('BB').text
        flbm.append(bb)

        spmc = bmxx.find('SPMC').text
        flbm.append(spmc)

        spbmjc = bmxx.find('SPBMJC').text
        flbm.append(spbmjc)

        kyzt = bmxx.find('KYZT').text
        flbm.append(kyzt)

        hzx = bmxx.find('HZX').text
        flbm.append(hzx)

        zzssl = bmxx.find('ZZSSL').text
        flbm.append(zzssl)

        gjz = bmxx.find('GJZ').text
        flbm.append(gjz)

        sm = bmxx.find('SM').text
        flbm.append(sm)

        csvwriter.writerow(flbm)
 
#with用法省掉了Flbm_data.close()

with open('spfwssflbm_yhzc.csv', 'w', newline='', encoding='utf_8_sig') as Yhzc_data:
    csvwriter = csv.writer(Yhzc_data)
    zzsyhzc_head = []
    count = 0
 
    for yhzc in root.findall('body/YHZC/ZZSYHZC'):
        zzsyhzc = []
     
        if count == 0:         
            yhzcmc ='优惠政策名称(' + yhzc.find('YHZCMC').tag + ')'
            zzsyhzc_head.append(yhzcmc)

            sl = '税率(' + yhzc.find('SL').tag + ')'
            zzsyhzc_head.append(sl)

            csvwriter.writerow(zzsyhzc_head)
            count = count + 1
         
        yhzcmc = yhzc.find('YHZCMC').text
        zzsyhzc.append(yhzcmc)

        sl = yhzc.find('SL').text
        zzsyhzc.append(sl)

        csvwriter.writerow(zzsyhzc)
     
#with用法省掉了Yhzc_data.close()

import pandas as pd
#相对路径
pd.read_csv('spfwssflbm_yhzc.csv').to_excel('spfwssflbm_yhzc.xlsx',index=False)

#绝对路径
filepath_in = r'C:\Users\XXX\spfwssflbm.csv'
filepath_out = r'C:\Users\XXX\spfwssflbm.xlsx'
df = pd.read_csv(filepath_in)
#避免商品编码变成科学计数法,版本号没有小数点
df['商品编码(SPBM)'] = df['商品编码(SPBM)'].apply(lambda x: '{:d}'.format(int(x)))
df['版本号(BB)'] = df['版本号(BB)'].apply(lambda x: '{:.1f}'.format(float(x)))
df.to_excel(filepath_out,index=False)





字段说明

BBH:版本号
MWJY:密文校验
COUNT:数量
BMXX:编码信息
BB:版本
QYSJ:启用时间
GDQJZSJ:过渡期截止时间
SPBM:商品编码
SPMC:商品名称
SPBMJC:商品编码简称
SM:说明
ZZSSL:增值税税率
GJZ:关键字
HZX:汇总项 即是否可归并上一级
KYZT:可用状态
ZZSTSGL:增值税特殊管理
ZZSZCYJ:增值税政策依据
ZZSTSNRDM:增值税特殊内容代码
XFSGL:消费税管理
XFSZCYJ:消费税政策依据
XFSTSNRDM:消费税特殊内容代码
TJJBM:统计局编码
HGJCKSPPM:海关进出口商品品目
PID
GXSJ:更新时间
YHZC:优惠政策
ZZSYHZC:增值税优惠政策
YHZCMC:优惠政策名称
SL:税率

评论

此博客中的热门博文

Mongo 入门

https://pymongo.readthedocs.io/en/stable/tutorial.html https://www.mongodb.com/languages/python https://zhuanlan.zhihu.com/p/51171906 https://www.runoob.com/python3/python-mongodb.html https://blog.baoshuo.ren/post/luogu-spider/ https://hub.docker.com/_/mongo 安装 MongoDB $ docker search mongo 启动一个mongo服务器实例 $ docker run --name some-mongo -d mongo:tag some-mongo是您要分配给容器的名称,tag是指定您想要的 MongoDB 版本的标签 MongoDB 的默认数据目录路径是/data/db 如下: $ docker run -it -v mongodata:/data/db -p 27017:27017 --name mongodb --restart unless-stopped -d mongo 你应该让 MongoDB 在端口 27017 上运行,并且可以通过localhostWindows 和 Ubuntu 20.04 上的URL访问 http://localhost:27017/ -p 是 HOST_PORT:CLIENT_PORT  -P 随机端口 -p 27017:27017 :将容器的27017 端口映射到主机的27017 端口 -v mongodata:/data/db :将主机中当前目录下的db挂载到容器的/data/db,作为mongo数据存储目录 从另一个 Docker 容器连接到 MongoDB 镜像中的 MongoDB 服务器侦听标准 MongoDB 端口27017,因此通过 Docker 网络连接将与连接到远程mongod. 以下示例启动另一个 MongoDB 容器实例,并mongo针对上述示例中的原始 MongoDB 容器运行命令行客户端,从而允许您针对数据库实例执行 MongoDB 语句: $ docker run -it --network some-network --...

端口映射 公网访问内网

https://portforward.com/ Holer 通过安全隧道将位于NAT和防火墙之后的本地服务器暴露给公共Internet。 Holer是一个将原型中的应用映射到公网访问的端口映射软件,支持转发基于TCP协议的报文 https://github.com/wisdom-projects/holer 方式一:使用(公告)的holer映射或者开通holer服务,通过holer客户端软件经 holer服务器实现公网访问。 公开的holer映射详情如下: 访问密钥 访问域名 公网地址 本地地址 使用场景 HOLER_CLIENT-2F8D8B78B3C2A0AE holer65530.wdom.net holer.org:65530 127.0.0.1:8080 网页 HOLER_CLIENT-3C07CDFD1BF99BF2 holer65531.wdom.net holer.org:65531 127.0.0.1:8088 网页 HOLER_CLIENT-2A623FCB6E2A7D1D holer65532.wdom.net holer.org:65532 127.0.0.1:80 网页 HOLER_CLIENT-AF3E6391525F70E4 不适用 holer.org:65533 127.0.0.1:3389 远程桌面 HOLER_CLIENT-822404317F9D8ADD 不适用 holer.org:65534 127.0.0.1:22 SSH协议 HOLER_CLIENT-27DD1389DF1D4DBC 不适用 holer.org:65535 127.0.0.1:3306 数据库 使用Java版本的holer客户端 ①java 1.7或者更高版本 ②下载holer-client.zip 修改配置文件C:\holer-client\conf\holer.conf HOLER_ACCESS_KEY=HOLER_CLIENT-2A623FCB6E2A7D1D HOLER_SERVER_HOST=holer65532.wdom.net ③建议先双击运行C:\holer-client\bin\shutdown.bat,再双击运行C:\holer-client\bin\startup.bat...

安装和卸载软件(msi\exe)

如何判断一个软件是64位的还是32位的? 情况1、 未安装--右键安装程序查看属性,兼容性,勾选兼容模式查看最低适配是vista的是64位,反之32位, 不太准确 情况2、 已安装--运行软件,64位操作系统打开任务管理器看进程后缀名,带*32就是32位,反之64位 https://www.joci.net/xxbk/126251/ FileMon 和 Regmon 不再可供下载。从Windows 2000 SP4,Windows XP SP2,Windows Server 2003 SP1和Windows Vista开始的Windows版本上,它们已被 Process Monitor 取代 https://adamtheautomator.com/procmon/ Process Monitor 是Windows的高级监视工具,它显示实时文件系统,注册表和进程/线程活动。 它结合了两个旧的Sysinternals实用程序 Filemon 和  Regmon的功能 ,并添加了广泛的增强功能列表,包括丰富的和非破坏性的过滤,全面的事件属性(例如会话ID和用户名),可靠的过程信息,带有集成符号的完整线程堆栈支持每个操作,同时记录到文件等。 它独特的强大功能将使Process Monitor成为您的系统故障排除和恶意软件搜索工具包中的核心实用程序。 https://wikileaks.org/ciav7p1/cms/page_42991626.html HKLM\Software\Microsoft\Cryptography\MachineGuid Machine GUID/Cryptography GUID---该密钥通常用作机器的唯一标识符。它也已用于将两台计算机链接在一起-在某些情况下,计算机GUID是与设备(MP3播放器等)一起传递的。 Machine GUID不是唯一 https://docs.microsoft.com/zh-cn/windows/win32/properties/props-system-identity-uniqueid?redirectedfrom=MSDN UniqueID才是唯一 注册表 是存储系统和应用程序的设置信息 打开注册表的方式很简单:cmd中输入regedit 卸载路径只有一个 已安装32位的程序,如果是系统是32位...