farpy项目

独自空忆成欢 提交于 2019-12-03 23:33:06

【前言】:经过一段时间的开发和试用,farpy的demo版基本成形。


 

【far】:financial analysis reporter的缩写


【场景】:需要对某个公司的财务情况进行分析,demo版只是协助完成一些财务分析模板的搭建,主要运用在银行客户经理撰写尽职调查报告时,有效的减少一个重复性的文字输入,可以节省时间在真正核心的分析中。

【后续】:后续将进一步完善财务分析的智能分析部分,财务指标是死的,分析结论才是活的,才是真正体现财务分析人员水平的地方。


 

【requirement】:

docxtpl==0.6.3et-xmlfile==1.0.1jdcal==1.4.1Jinja2==2.10.3lxml==4.4.1MarkupSafe==1.1.1openpyxl==3.0.0python-docx==0.8.7vnpy==1.9.2xlrd==1.2.0xlwt==1.3.0

  1 #!/usr/bin/python
  2 # -*- coding: utf-8 -*-
  3 #__author__:"watalo"
  4 #date: 2019/10/26
  5 
  6 '''
  7 1、固定格式的下列xlsx放在input文件夹中
  8 2、读取数据进入列表
  9 3、对列表数据进行文本操作
 10 '''
 11 
 12 from docx import Document
 13 from docx.oxml.ns import qn
 14 from openpyxl import load_workbook
 15 import os
 16 import rpt_module
 17 
 18 
 19 #全局变量声明
 20 name = 'XXX股份有限公司'
 21 
 22 #科目变量
 23 items = []
 24 date2y = []
 25 date1y = []
 26 date0y = []
 27 
 28 #路径变量
 29 rootpath = os.path.abspath(os.path.join(os.getcwd(),"..")) # reporter.py的上一级目录,目录下有input文件夹,
 30 datapath = ''.join([rootpath,r"\input\data.xlsx"])# 读取财务数据的xlsx格式文件
 31 
 32 #读取数据
 33 '''将固定格式的数据导入列表,列表就是长度为4的时间序列,列表[0]是变量名,后面是数据'''
 34 wb = load_workbook(filename = datapath)
 35 ws = wb["Sheet1"]
 36 year2 = ws.cell(1,2).value
 37 year1 = ws.cell(1,3).value
 38 year0 = ws.cell(1,4).value
 39 for row in ws.iter_rows(min_row=2,max_col=4,max_row=35):
 40     item = row[0].value
 41     items.append(str(item))
 42     date2 = float(row[1].value)
 43     date2y.append(date2)
 44     date1 = float(row[2].value)
 45     date1y.append(date1)
 46     date0 = float(row[3].value)
 47     date0y.append(date0)
 48 
 49 #编写报告
 50 #1、财务简表
 51 document = Document()
 52 document.styles['Normal'].font.name = u'宋体'
 53 document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
 54 head1 = '1、财务简表'
 55 run = document.add_heading('',level=1).add_run(head1)
 56 run.font.name=u'宋体'
 57 run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
 58 
 59 rows = list(ws.rows)
 60 table = document.add_table(rows = len(rows),
 61                            cols = len(rows[0]),
 62                            style = "Medium Shading 1 Accent 1")
 63 for irow, row in enumerate(rows):
 64     for icols, cols in enumerate(row):
 65         if type(cols.value) == str:
 66             table.cell(irow, icols).text = str(cols.value)
 67         else:
 68             i = round(float(cols.value),2)
 69             table.cell(irow,icols).text = str(i)#多出来一列,不知道怎么处理
 70 #初步判断,应该是后面一列出现了格式设置,但没有内容,不过openpyxl还是认定这列有内容,返回None值。
 71 
 72 #2、整体分析
 73 head2 = '2、整体评价'
 74 run = document.add_heading('',level=1).add_run(head2)
 75 run.font.name=u'宋体'
 76 run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
 77 
 78 #偿债能力
 79 text_modle2 = "截至%s末,该公司总资产%.2f万元,总负债%.2f万元,资产负债率%.2f%%,流动资产%.2f万元," \
 80               "流动负债%.2f万元,流动比率%.2f,速动比率%.2f,长期偿债能力%s,短期偿债能力%s,【%s】。"
 81 year = year0
 82 total_asset = float(ws.cell(2,4).value)
 83 total_debt = float(ws.cell(17,4).value)
 84 asset_liability_ratio = float(100*total_debt/total_asset)
 85 liquid_asset = float(ws.cell(3,4).value)
 86 liquid_debt = float(ws.cell(18,4).value)
 87 rate_of_liquid = float(ws.cell(61,4).value)
 88 rate_of_speed = float(ws.cell(62,4).value)
 89 
 90 long_slovency = ""
 91 if asset_liability_ratio  >= 70:
 92     long_slovency = "较弱"
 93 elif asset_liability_ratio >= 50 and asset_liability_ratio < 70:
 94     long_slovency = "一般"
 95 elif asset_liability_ratio >= 0 and asset_liability_ratio < 50:
 96     long_slovency = "较强"
 97 else:
 98     long_slovency = ""
 99 
100 short_slovency = ""
101 if rate_of_liquid  >= 1 and rate_of_speed >= 1:
102     short_slovency = "较强"
103 elif rate_of_liquid >= 1 and rate_of_speed < 1:
104     short_slovency = "一般"
105 elif rate_of_liquid < 1 and rate_of_speed < 1:
106     short_slovency = "较弱"
107 else:
108     short_slovency = ""
109 
110 all_commits = rpt_module.commits(long_slovency,short_slovency)
111 
112 text_set2 = (year, total_asset, total_debt, asset_liability_ratio, liquid_asset, liquid_debt, rate_of_liquid, rate_of_speed,
113                                                                             long_slovency, short_slovency, all_commits)
114 document.add_paragraph(text_modle2%text_set2)
115 
116 #盈利能力
117 # text_modle3 = ""
118 # 科目变化的表格展示
119 # 变化超过30%的科目
120 # document.add_table(c)
121 # for i in range(34):
122 #     if abs(rpt_module.data_format(date0y,date1y))>30:
123 
124 
125 #3、科目分析
126 head3 = '3、根据审计报告附注及尽职调查对【期末】主要财务数据分析'
127 run = document.add_heading('',level=1).add_run(head3)
128 run.font.name=u'宋体'
129 run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
130 
131     #函数
132 def item_table(colu1, colu2, colu3, colu4):
133     '''
134     需要导入python-docx
135     科目明细的表格制作,分为几种不同特点的表格体系:
136         detail:科目明细前五名(6rows 4columns)
137     :param style: 目前就这2个选项 var detail
138     :return: 表格样式
139     '''
140     table_regular = [colu1, colu2, colu3, colu4]
141     table = document.add_table(rows=7, cols=4, style='Medium Shading 2 Accent 1')
142     for i in range(4):
143         cell = table.cell(0, i)
144         cell.text = table_regular[i]
145     for i in range(5):
146         cell = table.cell(i + 1, 0)
147         cell.text = str(i + 1)
148 
149 
150 def para_format(items,date1y,date0y,type):
151     global liquid_asset
152     zf = rpt_module.data_format(date0y, date1y)
153     if type == "sa":
154         text_modle = "【%s】:%.2f万元,流动资产占比%.2f%%,较上年增加%.2f万元,增幅%.2f%%。"
155         item_in_sa = float(100*date0y/liquid_asset)
156         text_set = (items,  date0y, item_in_sa, date0y - date1y, zf)
157         return text_modle % text_set
158     elif type == "sd":
159         if total_asset-liquid_asset == 0:
160             pass
161         else:
162             text_modle = "【%s】:%.2f万元,流动负债占比%.2f%%,较上年增加%.2f万元,增幅%.2f%%。"
163             item_in_sd = float(100*date0y/liquid_debt)
164             text_set = (items,  date0y, item_in_sd, date0y - date1y, zf)
165             return text_modle % text_set
166     elif type == "la":
167         text_modle = "【%s】:%.2f万元,非流动资产占比%.2f%%,较上年增加%.2f万元,增幅%.2f%%。"
168         item_in_la = float(100*date0y/(total_asset-liquid_asset))
169         text_set = (items,  date0y, item_in_la, date0y - date1y, zf)
170         return text_modle % text_set
171     elif type == "ld":
172         if total_debt-liquid_debt == 0:
173             pass
174         else:
175             text_modle = "【%s】:%.2f万元,非流动负债占比%.2f%%,较上年增加%.2f万元,增幅%.2f%%。"
176             item_in_ld = float(100*date0y/(total_debt-liquid_debt))
177             text_set = (items,  date0y, item_in_ld, date0y - date1y, zf)
178             return text_modle % text_set
179     else:
180         pass
181 
182 '''对财务报表的各个科目进行格式化输出,明细内容需要调查后填写'''
183 for i in range(34): #对33个财务科目进行分析
184     if items[i] == "货币资金":
185         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
186             regular = para_format(items[i],date1y[i],date0y[i],"sa")
187             paragraph = document.add_paragraph(regular)
188             paragraph.add_run("其中现金【】万元,银行存款【】万元、其他货币资金【】万元。")
189         else:
190             pass
191 
192     elif items[i] == "应收票据":
193         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
194             regular = para_format(items[i], date1y[i], date0y[i],"sa")
195             paragraph = document.add_paragraph(regular)
196             paragraph.add_run("其中银行承兑汇票【】万元,商业承兑汇票【】万元。")
197         else:
198             pass
199 
200     elif items[i] == "应收账款":
201         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
202             regular = para_format(items[i], date1y[i], date0y[i],"sa")
203             paragraph = document.add_paragraph(regular)
204             paragraph.add_run("账面余额【】万元、计提坏账准备【】万元,账龄1年以内占比【】%,3年以上占比【】%。其中,应收账款前五位:")
205             item_table("序号", "名称", "余额(万元)", "占比")
206         else:
207             pass
208 
209     elif items[i] == "预付账款":
210         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
211             regular = para_format(items[i], date1y[i], date0y[i],"sa")
212             paragraph = document.add_paragraph(regular)
213             paragraph.add_run("账龄1年以内占比【】%,3年以上占比【】%。其中,预收账款前五位:")
214             item_table("序号", "名称", "余额(万元)", "占比")
215         else:
216             pass
217 
218     elif items[i] == "其他应收款":
219         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
220             regular = para_format(items[i], date1y[i], date0y[i],"sa")
221             paragraph = document.add_paragraph(regular)
222             paragraph.add_run("账面余额【】万元、计提坏账准备【】万元。其中,其他应付款前五位:")
223             item_table("序号", "名称", "余额(万元)", "款项性质")
224         else:
225             pass
226 
227     elif items[i] == "存货":
228         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
229             regular = para_format(items[i], date1y[i], date0y[i],"sa")
230             paragraph = document.add_paragraph(regular)
231             paragraph.add_run("其中,原材料【】万元、库存商品【】万元、周转材料【】万元、工程施工【】万元、开发成本【】万元。")
232         else:
233             pass
234 
235     elif items[i] == "其他流动资产":
236         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
237             regular = para_format(items[i], date1y[i], date0y[i],"sa")
238             paragraph = document.add_paragraph(regular)
239             paragraph.add_run("其中【添加明细】。")
240         else:
241             pass
242 
243     elif items[i] == "长期股权投资":
244         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
245             regular = para_format(items[i], date1y[i], date0y[i], "la")
246             paragraph = document.add_paragraph(regular)
247             paragraph.add_run("系对【填数字】家企业的投资,本期主要新增【哪家公司】;对外投资前五位如下:")
248             item_table("序号", "名称", "投资额", "投资性质")
249         else:
250             pass
251 
252     elif items[i] == "固定资产":
253         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
254             regular = para_format(items[i], date1y[i], date0y[i], "la")
255             paragraph = document.add_paragraph(regular)
256             paragraph.add_run("固定资产净值【】万元,累计折旧【】万元,其中房屋及建筑物【】万元、机器设备【】万元、办公设备【】万元、【其他】【】万元。")
257         else:
258             pass
259 
260     elif items[i] == "在建工程":
261         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
262             regular = para_format(items[i], date1y[i], date0y[i], "la")
263             paragraph = document.add_paragraph(regular)
264             paragraph.add_run("主要为【项目1】【】万元、【项目2】【】万元、【项目3】【】万元……")
265         else:
266             pass
267 
268     elif items[i] == "无形资产":
269         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
270             regular = para_format(items[i], date1y[i], date0y[i], "la")
271             paragraph = document.add_paragraph(regular)
272             paragraph.add_run("主要为土地使用权【】万元、采矿权【】万元、专利权【】万元、软件【】万元,其他【】万元。")
273         else:
274             pass
275 
276     elif items[i] == "短期借款":
277         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
278             regular = para_format(items[i], date1y[i], date0y[i], "sd")
279             paragraph = document.add_paragraph(regular)
280             paragraph.add_run("主要为【XX银行】【】万元、【XX银行】【】万元、【XX银行】【】万元、【xx银行】【】万元、【xx银行】【】万元。【其他需要说明的内容】")
281         else:
282             pass
283 
284     elif items[i] == "应付票据":
285         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
286             regular = para_format(items[i], date1y[i], date0y[i], "sd")
287             paragraph = document.add_paragraph(regular)
288             paragraph.add_run("主要为银行承兑汇票【】万元,商业承兑汇票【】万元。")
289         else:
290             pass
291 
292     elif items[i] == "应付账款":
293         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
294             regular = para_format(items[i], date1y[i], date0y[i], "sd")
295             paragraph = document.add_paragraph(regular)
296             paragraph.add_run("其中应付材料款【】万元,应付工程款【】万元。其中前五名如下:")
297             item_table("序号", "名称", "余额", "性质")
298         else:
299             pass
300 
301     elif items[i] == "预收账款":
302         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
303             regular = para_format(items[i], date1y[i], date0y[i], "sd")
304             paragraph = document.add_paragraph(regular)
305             paragraph.add_run("其中前5名如下:")
306             item_table("序号", "名称", "余额", "账龄")
307         else:
308             pass
309 
310     elif items[i] == "其他应付款":
311         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
312             regular = para_format(items[i], date1y[i], date0y[i], "sd")
313             paragraph = document.add_paragraph(regular)
314             paragraph.add_run("应付利息【】万元,往来款【】万元,押金和保证金【】万元,其中前5名如下:")
315             item_table("序号", "名称", "余额", "账龄")
316         else:
317             pass
318 
319     elif items[i] == "其他流动负债":
320         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
321             regular = para_format(items[i], date1y[i], date0y[i], "sd")
322             paragraph = document.add_paragraph(regular)
323             paragraph.add_run("主要为【】")
324         else:
325             pass
326 
327     elif items[i] == "长期借款":
328         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
329             regular = para_format(items[i], date1y[i], date0y[i], "ld")
330             paragraph = document.add_paragraph(regular)
331             paragraph.add_run("主要为【XX银行】【】万元、【XX银行】【】万元、【XX银行】【】万元、【xx银行】【】万元、【xx银行】【】万元。【其他需要说明的内容】")
332         else:
333             pass
334 
335     elif items[i] == "应付债券":
336         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
337             regular = para_format(items[i], date1y[i], date0y[i], "ld")
338             paragraph = document.add_paragraph(regular)
339             paragraph.add_run("主要为【】")
340         else:
341             pass
342 
343     elif items[i] == "长期应付款":
344         if date2y[i] != 0 or date1y[i] != 0 or date0y[i] != 0:
345             regular = para_format(items[i], date1y[i], date0y[i], "ld")
346             paragraph = document.add_paragraph(regular)
347             paragraph.add_run("其中专项应付款【】万元、【】【】万元、其他【】万元。")
348         else:
349             pass
350 
351 document.save("%s财务分析.docx"%name)
View Code

 

有兴趣共同开发的可以上github关注我,https://github.com/watalo/farpy


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!