Python 解析c文件并导出到Excel

脚本中主要使用 openpyxl cparser

1. 目录结构:

在这里插入图片描述

  • ast.txt :存放解析 c 文件的语法树,便于查找内容
  • cparser.py :解析 c 文件,并调用 write_excel.py 中封装的类写入 output.xlsx
  • output.xlsx : 存放以模板的样式存放函数
  • test.c : 需要解析的 c 文件
  • write_excel.py : 为 cparser.py 提供接口,写入 output.xlsx
  • 模板.xlsx : 模板样式

2.代码

1. test.c

#include <stdio.h>
#include <stdlib.h>

#define lsdl 2

int g_a =3;

void show(void)
{
    printf("hello show");
}

int add(int variate_a, int variate_b)
{
    int variate_c = variate_a * variate_b;
    variate_a += variate_b;
    variate_a += g_a;

    return variate_c-variate_a;
}

int main(void)
{
    int a =lsdl;
    int b =3;
    //printf("c = %d", add(a, b));
    return 0;
}

2. write_excel.py

import openpyxl
from openpyxl.styles import Alignment
import copy
import re

class WriterExcel():
    source_path = r'.\模板.xlsx'
    target_path = r'.\output.xlsx'

    source_temp_data_list = []

    copyfuncnum = 0



    def __init__(self, start_num) -> None:
        self.source_excel = openpyxl.load_workbook(self.source_path)
        self.source_Sheet1 = self.source_excel['Sheet1']
        self.source_Sheet2 = self.source_excel['Sheet2']
        
        self.target_excel = openpyxl.load_workbook(self.target_path)
        self.target_Sheet1 = self.target_excel['Sheet1']
        self.ClearSheet(self.target_Sheet1)

        self.start_num = start_num

    def ClearSheet(self, tagSheet):
        """
        @ 功能: 清空工作表
        @ 参数:目标工作表
        @ 返回值:
        """
        tagSheet.delete_rows(1, tagSheet.max_row)
        
        for row in tagSheet.iter_rows():
            for cell in row:
                cell.style = 'Normal'


    def CopyCell(self, sourow, sourcol, targrow, targcol):
        """
        @ 功能: 复制单元格的值、格式、填充色
        @ 参数:单元格源,工作表源,目标单元格,目标工作表
        @ 返回值:
        """

        self.target_Sheet1.cell(targrow, targcol).value = self.source_Sheet1.cell(sourow, sourcol).value  # 复制单元格的值
        if self.source_Sheet1.cell(sourow, sourcol).has_style:   # 判断该单元格是否有特殊格式
            self.target_Sheet1.cell(targrow, targcol).fill = copy.copy(self.source_Sheet1.cell(sourow, sourcol).fill)
            self.target_Sheet1.cell(targrow, targcol).border = copy.copy(self.source_Sheet1.cell(sourow, sourcol).border)
            self.target_Sheet1.cell(targrow, targcol).font = copy.copy(self.source_Sheet1.cell(sourow, sourcol).font)
            self.target_Sheet1.cell(targrow, targcol).alignment = copy.copy(self.source_Sheet1.cell(sourow, sourcol).alignment)

    def GetSourData(self):

        self.source_temp_data_list = self.source_Sheet1['A1:H16']  # 获取模板数据

    def WriteLine1(self, row, funcName):
        """
        @ Line 1
        """
        
        self.CopyCell(1, 1, row, 1)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=1, end_column=8)
        self.target_Sheet1.cell(row = row, column=1).alignment = Alignment(horizontal='left')

        self.target_Sheet1.cell(row= row, column= 1).value = f'1.{self.copyfuncnum +1} {funcName}'

    def WriteLine2(self, row):
        """
        @ Line 2
        """
        
        for col in range(1, 9):
            self.CopyCell(2, col, row, col)

    def WriteLine3(self, row):
        """
        @ Line 3
        """
        
        for col in range(1, 9):
            self.CopyCell(3, col, row, col)

        self.target_Sheet1.cell(row= row, column= 1).value = f'SWDD-BMU-{self.copyfuncnum +1}'

    def WriteLine4(self, row):
        """
        @ Line 3
        """
        
        self.CopyCell(4, 1, row, 1)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=1, end_column=8)

    def WriteLine5(self, row):
        """
        @ Line 5
        """
        
        for col in range(1, 9):
            self.CopyCell(5, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine6(self, row):
        """
        @ Line 6
        """
        
        for col in range(1, 9):
            self.CopyCell(6, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine7(self, row):
        """
        @ Line 7
        """
        
        for col in range(1, 9):
            self.CopyCell(7, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine8(self, row):
        """
        @ Line 8
        """
        
        for col in range(1, 9):
            self.CopyCell(8, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine9(self, row):
        """
        @ Line 9
        """
        
        for col in range(1, 9):
            self.CopyCell(9, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=5, end_column=8)

    def WriteLine10(self, row, paraList):
        """
        @ Line 10
        """

        if len(paraList) >= 1:
            for index in range(len(paraList)):
                for col in range(1, 9):
                    self.CopyCell(10, col, row, col)
                self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=5, end_column=8)

                if paraList[index][0] != None:
                    self.target_Sheet1.cell(row= row, column= 3).value = paraList[index][0]
                    self.target_Sheet1.cell(row= row, column= 4).value = paraList[index][1]
                else:
                    self.target_Sheet1.cell(row= row, column= 2).value = '-'
                row += 1
        else:
            for col in range(1, 9):
                self.CopyCell(10, col, row, col)
            self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=5, end_column=8)

    def WriteLine11(self, row, retList):
        """
        @ Line 11
        """
        for col in range(1, 9):
            self.CopyCell(11, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=5, end_column=8)

        if len(retList) != 0:
            self.target_Sheet1.cell(row= row, column= 3).value = retList[0]
            self.target_Sheet1.cell(row= row, column= 4).value = retList[1]
        else:
            self.target_Sheet1.cell(row= row, column= 2).value = '-'


    def WriteLine12(self, row):
        """
        @ Line 12
        """
        for col in range(1, 9):
            self.CopyCell(12, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

    def WriteLine13(self, row, fileName):
        """
        @ Line 13
        """
        for col in range(1, 9):
            self.CopyCell(13, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)

        self.target_Sheet1.cell(row= row, column= 2).value = fileName

    def WriteLine14(self, row):
        """
        @ Line 14
        """
        for col in range(1, 9):
            self.CopyCell(14, col, row, col)
        self.target_Sheet1.merge_cells(start_row= row, end_row= row, start_column=2, end_column=8)


    def SaveAll(self):
        self.target_excel.save(self.target_path)
        self.source_excel.save(self.source_path)

3. cparser.py

# parser_file 用于处理c语言文件
from pycparser import parse_file
from pycparser import CParser
# c语言有错误时,会引出此错误
from pycparser.plyparser import ParseError
# c_ast.py 文件下包含了抽象语法树的节点类
from pycparser.c_ast import *

import write_excel
from write_excel import WriterExcel



class CParserInfo:
    current_line = 1
    def __init__(self, filename:str):
        self.filename = filename

        m_cpp_path=r'C:\MinGW\bin\gcc.exe'
        m_cpp_args=['-E', r'-Iutils/fake_libc_include']
        self.ast = parse_file(filename, use_cpp = True, cpp_path=m_cpp_path, cpp_args= m_cpp_args)

        self.writeExcHander = WriterExcel(1)

    def ProcessTreeNode(self):
        for FuncDecNope in self.ast.ext:
            
            if FuncDecNope.__class__.__name__ == 'FuncDef':
                self.ProcessLine1(FuncDecNope)
                self.ProcessLine2()
                self.ProcessLine3()
                self.ProcessLine4()
                self.ProcessLine5()
                self.ProcessLine6()
                self.ProcessLine7()
                self.ProcessLine8()
                self.ProcessLine9()
                self.ProcessLine10(FuncDecNope)
                self.ProcessLine11(FuncDecNope)
                self.ProcessLine12()
                self.ProcessLine13(FuncDecNope)
                self.ProcessLine14()
                self.writeExcHander.copyfuncnum += 1

    def ProcessLine1(self, funcDef):
        """
        @ Line 1
        """
        m_declNode = funcDef.decl

        print(m_declNode.name)
        self.writeExcHander.WriteLine1(row = self.current_line, funcName= m_declNode.name)
        self.current_line += 1
        
    def ProcessLine2(self):
        """
        @ Line 2
        """
        
        self.writeExcHander.WriteLine2(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine3(self):
        """
        @ Line 3
        """
        
        self.writeExcHander.WriteLine3(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine4(self):
        """
        @ Line 4
        """
        
        self.writeExcHander.WriteLine4(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine5(self):
        """
        @ Line 5
        """
        
        self.writeExcHander.WriteLine5(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine6(self):
        """
        @ Line 6
        """
        
        self.writeExcHander.WriteLine5(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine7(self):
        """
        @ Line 7
        """
        
        self.writeExcHander.WriteLine7(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine8(self):
        """
        @ Line 8
        """
        
        self.writeExcHander.WriteLine8(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine9(self):
        """
        @ Line 9
        """
        
        self.writeExcHander.WriteLine9(row = self.current_line)
        self.current_line += 1
        
    def ProcessLine10(self, funcDef):
        """
        @ Line 10
        """
        m_paraList = []

        para_len = len(funcDef.decl.type.args.params)
        print('para_len = ', para_len)
        for index in range(para_len):
            tmp_paraList = funcDef.decl.type.args.params[index]
            tmp_list = []
            if tmp_paraList.name != 'None':
                tmp_list.append(tmp_paraList.name)
                tmp_list.append(tmp_paraList.type.type.names[0])
            m_paraList.append(tmp_list)

        self.writeExcHander.WriteLine10(row = self.current_line, paraList= m_paraList)

        if len(m_paraList) > 1:
            self.current_line += len(m_paraList)
        else:
            self.current_line += 1
        
    def ProcessLine11(self, funcDef):
        """
        @ Line 11
        """
        m_retList = []

        m_blockItem = funcDef.body.block_items

        m_tmpList = []
        for eachNode in m_blockItem:
            m_tmpList.append(eachNode.__class__.__name__)

        if 'Return' not in m_tmpList :
            print('不在')
            self.writeExcHander.WriteLine11(row = self.current_line, retList= m_retList)
            self.current_line += 1
            return

        for eachNode in m_blockItem:
            if eachNode.__class__.__name__ == 'Return':
                if eachNode.expr.__class__.__name__ == 'Constant':
                    m_retList.append(eachNode.expr.value)
                    m_retList.append(funcDef.decl.type.type.type.names[0])
                elif eachNode.expr.__class__.__name__ == 'BinaryOp':
                    if eachNode.expr.op == '-':
                        m_retList.append(eachNode.expr.left.name + eachNode.expr.op + eachNode.expr.right.name)
                        m_retList.append(funcDef.decl.type.type.type.names[0])
        

        self.writeExcHander.WriteLine11(row = self.current_line, retList= m_retList)

        self.current_line += 1
        
    def ProcessLine12(self):
        """
        @ Line 12
        """
        self.writeExcHander.WriteLine12(row = self.current_line)
        self.current_line += 1

    def ProcessLine13(self, funcDef):
        """
        @ Line 13
        """
        self.writeExcHander.WriteLine13(row = self.current_line, fileName= funcDef.coord.file)
        self.current_line += 1

    def ProcessLine14(self):
        """
        @ Line 14
        """
        self.writeExcHander.WriteLine14(row = self.current_line)
        self.current_line += 1

    def SaveExtToTxt(self):
        with open('ast.txt', encoding='utf-8', mode= 'w+') as f:
            f.write(str(self.ast.ext))


def main():

    m_filename = 'test.c'
    m_fileInfo = CParserInfo(m_filename)
    m_fileInfo.ProcessTreeNode()
    m_fileInfo.SaveExtToTxt()

    m_fileInfo.writeExcHander.SaveAll()

if __name__ == '__main__'        :
    main()

4. 模板.xlsx

在这里插入图片描述

5. output.xlsx

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要用 Python 获取银行联行号,您需要找到一个数据源,并使用 Python 进行爬取和处理。通常,银行联行号数据可以在政府网站或金融机构网站上获得,您可以使用 Python 中的爬虫库(如 BeautifulSoup)进行爬取。 在处理完数据之后,您可以使用 Python 中的库(如 pandas)将数据存储到 DataFrame 中,并使用 pandas 的 to_excel 方法将数据导出Excel 文件中。 代码示例: ``` import requests from bs4 import BeautifulSoup import pandas as pd # 获取数据 url = "https://www.example.com/bank-codes" res = requests.get(url) soup = BeautifulSoup(res.text, "html.parser") # 处理数据 bank_codes = [] table = soup.find("table") for row in table.find_all("tr"): cols = row.find_all("td") if len(cols) >= 2: bank_name = cols[0].text.strip() bank_code = cols[1].text.strip() bank_codes.append([bank_name, bank_code]) # 将数据存储到 DataFrame 中 df = pd.DataFrame(bank_codes, columns=["银行名称", "银行联行号"]) # 导出Excel 文件中 df.to_excel("bank_codes.xlsx", index=False) ``` 请注意,此代码仅作为示例,实际情况可能有所不同,您需要根据您所使用的数据源进行相应的修改。 ### 回答2: 用Python获取银行联行号并导出Excel文件需要以下步骤: 1. 导入所需模块:使用Python,我们需要导入一些模块,如`requests`用于发送HTTP请求,`beautifulsoup4`用于爬取网页数据,`openpyxl`用于操作Excel文件。 2. 发送HTTP请求获取网页数据:使用`requests`模块发送HTTP请求,访问包含银行联行号的网页,并获取到网页的HTML内容。 3. 解析网页数据:使用`beautifulsoup4`模块解析网页的HTML内容,找到包含银行联行号的格或列。 4. 提取银行联行号:根据网页的结构,使用`beautifulsoup4`模块提取出银行联行号,并将其保存到一个列或字典中。 5. 创建并操作Excel文件:使用`openpyxl`模块创建一个新的Excel文件,设置头和列的名称。遍历银行联行号列或字典,将数据写入Excel文件的相应单元格。 6. 保存Excel文件:将完成数据写入Excel文件后,使用`openpyxl`模块保存Excel文件,生成最终的导出文件。 以上是基本的步骤,具体代码可以根据实际需求进行调整和优化。这个过程需要一定的Python编程基础和对相关模块的了解。 ### 回答3: 要通过Python获取银行联行号并导出Excel文件,可以采用以下步骤: 1. 导入所需的Python库,如pandas、openpyxl和requests。 ```python import pandas as pd import openpyxl import requests ``` 2. 创建一个函数,用于获取银行联行号。这可以通过调用一个提供银行数据的API来实现。以下是一个示例函数: ```python def get_bank_info(bank_name): api_url = "https://api.example.com/bank_info" params = {"name": bank_name} response = requests.get(api_url, params=params) bank_info = response.json() return bank_info["bank_code"] ``` 这个函数接受银行名称作为参数,并返回对应的银行联行号。 3. 创建一个空的数据框,用于保存银行名称和联行号。 ```python bank_data = pd.DataFrame(columns=["银行名称", "联行号"]) ``` 4. 循环遍历需要查询的银行列,并调用上述函数获取联行号,并将结果添加到数据框中。 ```python bank_list = ["工商银行", "建设银行", "中国银行"] for bank in bank_list: bank_code = get_bank_info(bank) bank_data = bank_data.append({"银行名称": bank, "联行号": bank_code}, ignore_index=True) ``` 5. 将数据框保存为Excel文件。 ```python bank_data.to_excel("bank_info.xlsx", index=False) ``` 以上代码将数据保存为名为"bank_info.xlsx"的Excel文件,index=False示不保存索引列。 完整的代码示例: ```python import pandas as pd import openpyxl import requests def get_bank_info(bank_name): api_url = "https://api.example.com/bank_info" params = {"name": bank_name} response = requests.get(api_url, params=params) bank_info = response.json() return bank_info["bank_code"] bank_data = pd.DataFrame(columns=["银行名称", "联行号"]) bank_list = ["工商银行", "建设银行", "中国银行"] for bank in bank_list: bank_code = get_bank_info(bank) bank_data = bank_data.append({"银行名称": bank, "联行号": bank_code}, ignore_index=True) bank_data.to_excel("bank_info.xlsx", index=False) ``` 运行以上代码后,将在当前目录下生成一个名为"bank_info.xlsx"的文件,其中包含了从API获取的银行联行号的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值