1 上市公司年报格式准则–说明

上市公司每年皆应发布上一年度年报,且须符合证监会制定之格式准则。严格来说,上市公司年报格式准则全称为—《公开发行证券的公司信息披露内容与格式准则第2号—年度报告的内容与格式》。证监会对年报格式准则,会不断地进行修订。近些年进行了四次修订:

2 提取不同修订版目录准则代码

为了了解不同修订版的要求,我用如下Python代码,提取了关于年报目录准则。

import os
import re
import fitz # pip install pymupdf
import csv

filenames = os.listdir()
prefix = '公开发行证券的公司信息披露内容与格式准则第2号'

# 须点击上面列表中链接,下载四个修订版本PDF文件,
# 并放置在该代码文件所在文件夹。

# 筛选出格式准则文件
pdf = [f for f in filenames if f.startswith(prefix) and f.endswith('.pdf')]
# 提取修订年份
year = [f[-12:-5] for f in pdf]

# 提取PDF文本,因有一份无法被pdfplumber库提取,故采用pymupdf
def getText(pdf):
    text = ''
    doc = fitz.open(pdf)
    for page in doc:
        text += page.getText()
    doc.close()
    return(text)


# 主要部分
def getTOC(pdf):
    text = getText(pdf)
    p1 = re.compile('第二章\s*年度报告正文(.*)第三章\s*年度报告摘要',re.DOTALL)
    subtext = p1.search(text).group(0)
    p = re.compile('(?<=\\n)(第\w{1,2}节)\s+(.*)(?=\\n)')
    listOftuple = p.findall(subtext)
    return(listOftuple)

# text_list = [getText(f) for f in pdf]
toc = [getTOC(f) for f in pdf]


# 存储至 '.csv' 文件,方便后续使用。
def to_csv(year,toc):
    with open(year+'.csv', mode='w', newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        for t in toc:
            writer.writerow([t[0],t[1]])
    return

for i in range(len(year)):
    to_csv(year[i], toc[i])

3 目录准则 对比表

2012年修订 2016年修订 2017年修订 2021年修订
第一节 重要提示、目录和释义 重要提示、目录和释义 重要提示、目录和释义 重要提示、目录和释义
第二节 公司简介 公司简介和主要财务指标 公司简介和主要财务指标 公司简介和主要财务指标
第三节 会计数据和财务指标摘要 公司业务概要 公司业务概要 管理层讨论与分析
第四节 董事会报告 经营情况讨论与分析 经营情况讨论与分析 公司治理
第五节 重要事项 重要事项 重要事项 环境和社会责任
第六节 股份变动及股东情况 股份变动及股东情况 股份变动及股东情况 重要事项
第七节 董事、监事、高级管理人员和员工情况 优先股相关情况 优先股相关情况 股份变动及股东情况
第八节 公司治理 董事、监事、高级管理人员和员工情况 董事、监事、高级管理人员和员工情况 优先股相关情况
第九节 内部控制 公司治理 公司治理 债券相关情况
第十节 财务报告 公司债券相关情况 公司债券相关情况 财务报告
第十一节 财务报告 财务报告
第十二节 备查文件目录 备查文件目录

4 目录准则 各修订表

4.1 2021年—目录准则

第一节 重要提示、目录和释义
第二节 公司简介和主要财务指标
第三节 管理层讨论与分析
第四节 公司治理
第五节 环境和社会责任
第六节 重要事项
第七节 股份变动及股东情况
第八节 优先股相关情况
第九节 债券相关情况
第十节 财务报告

4.2 2017年—目录准则

第一节 重要提示、目录和释义
第二节 公司简介和主要财务指标
第三节 公司业务概要
第四节 经营情况讨论与分析
第五节 重要事项
第六节 股份变动及股东情况
第七节 优先股相关情况
第八节 董事、监事、高级管理人员和员工情况
第九节 公司治理
第十节 公司债券相关情况
第十一节 财务报告
第十二节 备查文件目录

4.3 2016年—目录准则

第一节 重要提示、目录和释义
第二节 公司简介和主要财务指标
第三节 公司业务概要
第四节 经营情况讨论与分析
第五节 重要事项
第六节 股份变动及股东情况
第七节 优先股相关情况
第八节 董事、监事、高级管理人员和员工情况
第九节 公司治理
第十节 公司债券相关情况
第十一节 财务报告
第十二节 备查文件目录

4.4 2012年—目录准则

第一节 重要提示、目录和释义
第二节 公司简介
第三节 会计数据和财务指标摘要
第四节 董事会报告
第五节 重要事项
第六节 股份变动及股东情况
第七节 董事、监事、高级管理人员和员工情况
第八节 公司治理
第九节 内部控制
第十节 财务报告

6 第二次作业提示

6.1 html 模板

html模板: homework2_output_template.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <style media="screen">
      h3 {
        text-align: center;
        margin-top: 50px;
      }
      p {
        margin-top: 20px;
        margin-bottom: 20px;
        margin:auto;
        max-width: 500px;
      }
    </style>
  </head>
  <body>
      %s
  </body>
</html>

6.2 示例代码

import os
import re
import fitz # pip install pymupdf
import csv

filenames = os.listdir()
prefix = '公开发行证券的公司信息披露内容与格式准则第2号'

# 须点击上面列表中链接,下载四个修订版本PDF文件,
# 并放置在该代码文件所在文件夹。

# 筛选出格式准则文件
pdf = [f for f in filenames if f.startswith(prefix) and f.endswith('.pdf')]
# 提取修订年份
year = [f[-12:-5] for f in pdf]

# 提取PDF文本,因有一份无法被pdfplumber库提取,故采用pymupdf
def getText(pdf):
    text = ''
    doc = fitz.open(pdf)
    for page in doc:
        text += page.getText()
    doc.close()
    return(text)

def getSubtext(pdf):
    text = getText(pdf)
    p1 = re.compile('第二章\s*年度报告正文(.*)第三章\s*年度报告摘要',
                    re.DOTALL)
    subtext = p1.search(text).group(0)
    return(subtext)

# 主要部分
def getTOC(pdf):
    subtext = getSubtext(pdf)
    p = re.compile('(?<=\\n)(第\w{1,2}节)\s+(.*)(?=\\n)')
    listOftuple = p.findall(subtext)
    return(listOftuple)

# text_list = [getText(f) for f in pdf]
toc = [getTOC(f) for f in pdf]

def getTOC_content(pdf):
    subtext = getSubtext(pdf)
    p = re.compile('(?<=\\n)(第\w{1,2}节)\s+(.*)(?=\\n)')
    index = []
    for match in p.finditer(subtext):
        s = match.start()
        e = match.end()
        index.append((s,e))
    #
    content = []
    for i in range(len(index)-1):
        s = index[i][1]
        e = index[i+1][0]
        content.append(subtext[s:e])
    last_start = index[-1][1]
    last_end = subtext.rfind('\n第三章')
    content.append(subtext[last_start:last_end])
    return((index,content))

# index, content = getTOC_content(pdf[0])
list_of_content = [getTOC_content(f) for f in pdf]

def export_to_html(pdf,toc,content):
    f = open('homework2_output_template.html', encoding='utf-8')
    html = f.read()
    f.close()
    template = '<div><h3>%s</h3><p>%s</p></div>'
    toc_list = [t[0]+' '+ t[1] for t in toc]
    div = [template % (t,c) for (t,c) in zip(toc_list, content)]
    div = ''.join(div)
    html = html % div
    f = open('homework2_%s.html' % pdf, 'w',encoding='utf-8')
    f.write(html)
    f.close()
    return()

content_list = [c[1] for c in list_of_content]
export_to_html(pdf[0], toc[0], content_list[0])