张世豪 3 months ago
commit
5133de4ff8

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 16 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,16 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="ignoredPackages">
+        <value>
+          <list size="3">
+            <item index="0" class="java.lang.String" itemvalue="opencv-python" />
+            <item index="1" class="java.lang.String" itemvalue="imageio-ffmpeg" />
+            <item index="2" class="java.lang.String" itemvalue="torch" />
+          </list>
+        </value>
+      </option>
+    </inspection_tool>
+  </profile>
+</component>

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 7 - 0
.idea/misc.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Black">
+    <option name="sdkName" value="D:\software\anaconda\envs\py38" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="D:\software\anaconda\envs\py38" project-jdk-type="Python SDK" />
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/代码.iml" filepath="$PROJECT_DIR$/.idea/代码.iml" />
+    </modules>
+  </component>
+</project>

+ 8 - 0
.idea/代码.iml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="jdk" jdkName="D:\software\anaconda\envs\py38" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

BIN
__pycache__/partReport.cpython-38.pyc


BIN
__pycache__/public.cpython-38.pyc


BIN
__pycache__/report.cpython-38.pyc


+ 1 - 0
html/code.txt

@@ -0,0 +1 @@
+7687698709809hjkjlipomuiyoiupoimvgfghuli376d8bf8f8855ad8de997fa5dac1bd24956aef0cbfa0cf8ac04053a7043e3d90248051f6f03f02b20430949504a5556fb112131fc81205768229ffa023831b04

+ 1 - 0
html/config.txt

@@ -0,0 +1 @@
+376d8bf8f8855ad8de997fa5dac1bd24956aef0cbfa0cf8ac04053a7043e3d90248051f6f03f02b20430949504a5556fb112131fc81205768229ffa023831b04

BIN
img/icon.ico


BIN
img/logo_1.ico


BIN
img/logo_1.jpg


BIN
img/logo_2.ico


BIN
img/logo_2.jpg


BIN
img/土壤数据审核软件图标.png


BIN
img/数值修约要求.xlsx


+ 1972 - 0
partReport.py

@@ -0,0 +1,1972 @@
+import pandas as pd
+import numpy as np
+import time
+import os
+from docx.shared import Inches
+from docx.shared import Pt, RGBColor
+from docx import Document
+from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT
+from docx.oxml.ns import qn
+from docx.enum.text import WD_ALIGN_PARAGRAPH
+from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
+import report
+
+# 频度信息表生成
+def makeInfoTable(data, doc):
+    rows = (int(len(data.columns) / 6) + 1)
+    columnsList = np.arange(0, rows * 6, 6)
+    dataList = []
+    for i in columnsList:
+        res = data.iloc[:, i:i + 6]
+        res = res.reset_index()
+        dataList.append(res)
+    table_f_2 = doc.add_table(rows=rows * 6, cols=7, style='Light Shading Accent 1')
+    for i, row in enumerate(table_f_2.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == columnsList[0]:
+                # 第一行 显示前6个指标的列名
+                if len(dataList[0].columns) > j:
+                    r = paragraph.add_run(dataList[0].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 1 and i > columnsList[0] and i < columnsList[1]:
+                if len(dataList[0].columns) > j:
+                    r = paragraph.add_run(str(dataList[0].iloc[i - 1, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[1]:
+                # 第6行 显示前6个指    标的列名
+                if len(dataList[1].columns) > j:
+                    r = paragraph.add_run(dataList[1].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 2 and i > columnsList[1] and i < columnsList[2]:
+                if len(dataList[1].columns) > j:
+                    r = paragraph.add_run(str(dataList[1].iloc[i - 7, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[2]:
+                # 第6*2行 显示前6个指    标的列名
+                if len(dataList[2].columns) > j:
+                    r = paragraph.add_run(dataList[2].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 3 and i > columnsList[2] and i < columnsList[3]:
+                if len(dataList[2].columns) > j:
+                    r = paragraph.add_run(str(dataList[2].iloc[i - 13, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[3]:
+                # 第6*3行 显示前6个指    标的列名
+                if len(dataList[3].columns) > j:
+                    r = paragraph.add_run(dataList[3].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 4 and i > columnsList[3] and i < columnsList[4]:
+                if len(dataList[3].columns) > j:
+                    r = paragraph.add_run(str(dataList[3].iloc[i - 19, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[4]:
+                # 第6*4行 显示前6个指    标的列名
+                if len(dataList[4].columns) > j:
+                    r = paragraph.add_run(dataList[4].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 5 and i > columnsList[4] and i < columnsList[5]:
+                if len(dataList[4].columns) > j:
+                    r = paragraph.add_run(str(dataList[4].iloc[i - 25, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[5]:
+                # 第6*5行 显示前6个指 标的列名
+                if len(dataList[5].columns) > j:
+                    r = paragraph.add_run(dataList[5].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 6 and i > columnsList[5] and i < columnsList[6]:
+                if len(dataList[5].columns) > j:
+                    r = paragraph.add_run(str(dataList[5].iloc[i - 31, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[6]:
+                # 第6*6行 显示前6个指    标的列名
+                if len(dataList[6].columns) > j:
+                    r = paragraph.add_run(dataList[6].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 7 and i > columnsList[6] and i < columnsList[7]:
+                if len(dataList[6].columns) > j:
+                    r = paragraph.add_run(str(dataList[6].iloc[i - 37, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[7]:
+                # 第6*7行 显示前6个指    标的列名
+                if len(dataList[7].columns) > j:
+                    r = paragraph.add_run(dataList[7].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) >= 8 and i > columnsList[7] and i < columnsList[8]:
+                if len(dataList[7].columns) > j:
+                    r = paragraph.add_run(str(dataList[7].iloc[i - 43, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[8]:
+                if len(dataList[8].columns) > j:
+                    # 第6*8行 显示前6个指    标的列名
+                    r = paragraph.add_run(dataList[8].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) >= 9 and i > columnsList[8] and i < columnsList[9]:
+                if len(dataList[8].columns) > j:
+                    r = paragraph.add_run(str(dataList[8].iloc[i - 49, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[9]:
+                # 第6*9行 显示前6个指    标的列名
+                if len(dataList[9].columns) > j:
+                    r = paragraph.add_run(dataList[9].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) >= 10 and i > columnsList[9] and i <= 60:
+                if len(dataList[9].columns) > j:
+                    r = paragraph.add_run(str(dataList[9].iloc[i - 55, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+# 生成子报告: 物理指标 常规养分指标 一般化学性指标 重金属指标
+indexClassificationList = {
+    '物理指标': ['pH', '土壤质地', '土壤容重1(g/cm³)', '土壤容重2(g/cm³)', '土壤容重3(g/cm³)',	'土壤容重4(g/cm³)',	'土壤容重平均值(g/cm³)',
+                 '2~0.2mm颗粒含量', '0.2~0.02mm颗粒含量',	'0.02~0.002mm颗粒含量',	'0.002mm以下颗粒含量', '水稳>5mm(%)',	'水稳3mm~5mm(%)',
+                 '水稳2mm~3mm(%)',	'水稳1mm~2mm(%)',	'水稳0.5mm~1mm(%)',	'水稳0.25mm~0.5mm(%)',	'水稳性大团聚体总和(%)', '洗失量(吸管法需填)', '风干试样含水量(分析基)'],
+    '常规养分指标': ['pH','有机质', '全氮', '全磷', '全钾', '有效磷', '速效钾', '有效硫', '有效硼', '有效铁', '有效锰', '有效铜', '有效锌', '有效钼', '有效硅', '缓效钾'],
+    '一般化学性指标': ['pH','阳离子交换量', '交换性盐基总量', '交换性钙', '交换性镁', '交换性钠', '交换性钾', '全盐量', '电导率',
+                       '水溶性Na⁺含量', '水溶性K⁺含量',	'水溶性Ca²⁺含量',	'水溶性Mg²⁺含量',	'水溶性Cl⁻含量', '水溶性CO₃²⁻含量','水溶性HCO₃⁻含量',
+                       '水溶性SO₄²⁻含量', '离子总量', '碳酸钙'],
+    '重金属指标': ['pH', '总汞', '总砷', '总铅', '总镉', '总铬', '总镍']
+}
+# 生成物理指标审核报告
+def  getphysicsReport(data,type, changeFileUrl, saveFileUrl, check_1_data,
+    check_3_data,
+    check_5_data ,
+    check_8_data,  # 样品编号替换为编号
+    check_10_data,
+    check_12_data,
+    check_14_data ):
+    """
+
+    :param type: 指标类型
+    :param changeFileUrl: 选择的数据文件路径
+    :param saveFileUrl: 保存的文件路径
+    :param check_1_data: 土壤容重数据
+    :param check_3_data: 水稳审核数据
+    :param check_5_data: 盐离子数据
+    :param check_8_data: 水溶性离子数据
+    :param check_10_data: 有机质及氮磷钾数据
+    :param check_12_data: 有效养分数据
+    :param check_14_data: 重金属数据
+    :return:
+    """
+    # 生成报告
+    name = os.path.basename(changeFileUrl)
+    n = name.split('.')
+    areaName = n[0].replace('数据', '')
+    # 生成一个新的文件夹用于存放审核报告相关的数据
+    nowTime = time.strftime("%Y-%m-%d %H时%M分%S秒", time.localtime())
+    dir_name = f'{areaName}-{type}数据审核报告'
+    mkdir_path = saveFileUrl + '/' + dir_name + nowTime
+    if not os.path.exists(mkdir_path):
+        os.mkdir(mkdir_path)
+    # 获取相应指标数据
+    physicsData = data[indexClassificationList[type]]
+    report.getFrequencyImage(physicsData, mkdir_path)
+    physicsData['序号'] = data['序号']
+    physicsData['原样品编号'] = data['原样品编号']
+    physicsData['样品编号'] = data['样品编号']
+    physicsData['地理位置'] = data['地理位置']
+    physicsData['母质'] = data['母质']
+    physicsData['土壤类型'] = data['土壤类型']
+    physicsData['土地利用类型'] = data['土地利用类型']
+    physicsData['土壤质地'] = data['土壤质地']
+    # 生成相应审核报告
+    # 根据选择的路径读取数据
+    physicsData['原样品编号'] = physicsData['原样品编号'].astype(str)
+    # todo 有数据后这里去掉注释
+    # checkData = pd.read_excel(changeFileUrl, sheet_name='检测方法')
+
+    # 上面这个地址,可以传递给函数中,用于保存表格和图片
+    # 调用函数 开始生成报告相关内容
+    # 表1相关数据
+    typeData = report.getSimpleNum(physicsData)
+    lenNum_1 = len(typeData['sData'])
+    lenNum_1_f = len(typeData['allData'])
+    table_1_data = pd.DataFrame({
+        '类型': typeData['sData'].index,
+        '数量': typeData['sData'],
+        '合计': [typeData['sData'].sum() for _ in range(lenNum_1)]
+    })
+    # 表2数据
+    table_2_data = report.getDataComplete(physicsData)
+    table_2_data = table_2_data.reset_index()
+    table_2_data.columns = ['指标名称', '实测数量', '应测数量']
+    # 表3数据
+    # table_3_data = report.checkMethod(checkData, mkdir_path)
+    # 数据修约 表4
+    report.getNum(physicsData, mkdir_path)
+    # 数据填报项审核 表5
+    report.dataReportResult(physicsData, mkdir_path)
+    # 表6数据 土壤质地类型不一致
+    middData = physicsData[['原样品编号', '样品编号']].astype(str)
+    middData['编号'] = middData['原样品编号']
+    del middData['原样品编号']
+
+    check_1_data = pd.merge(check_1_data, middData, how='left', on='编号')
+    check_1_data = check_1_data.replace(np.nan, '')
+    typeNotSame = check_1_data[check_1_data['土壤质地'] != check_1_data['土壤类型(判断)']]
+    table_6_data = typeNotSame[['编号', '样品编号', '土壤质地', '土壤类型(判断)']]
+    allNeedData = pd.DataFrame({})
+    allNeedData['原样品编号'] = check_1_data['编号']
+    getSimpleDataNumber = pd.merge(allNeedData, physicsData[['原样品编号', '样品编号']], how='left', on="原样品编号")
+    allNeedData['样品编号'] = getSimpleDataNumber['样品编号']
+    allNeedData['土地利用类型'] = check_1_data['土地利用类型']
+    allNeedData['审核结果'] = check_1_data['审核结果'] + check_3_data['审核结果']
+    allNeedData['外业'] = ['' for _ in range(len(check_1_data))]
+    table_7_data = allNeedData[allNeedData['审核结果'] != '']
+    del table_7_data['审核结果']
+    # 写进表格
+    with pd.ExcelWriter(f'{mkdir_path}/超阈值样品统计表.xlsx', engine='openpyxl') as writer:
+        table_7_data.to_excel(writer, index=False, sheet_name='超阈值数据')
+
+    # 表8数据
+    table_8_data = report.getPHData(physicsData, mkdir_path)
+
+    # 表13 所有存疑数据
+    with pd.ExcelWriter(f'{mkdir_path}/数据审核过程存疑数据一览表.xlsx', engine='openpyxl') as writer:
+        allNeedData[allNeedData['审核结果'] != ''].to_excel(writer, index=False, sheet_name='存疑数据')
+    # 附表: 频度分析图
+    # report.getFrequencyImage(physicsData, mkdir_path)
+    table_f_2_data = report.getFrequencyInformation(data, mkdir_path)
+    # 新建一个文档
+    doc = Document()
+    # 添加标题
+    doc.add_heading(f"{areaName}第三次全国土壤普查数据审核报告", level=0)
+    # 添加一级标题
+    doc.add_heading('一、数据完整性审核', level=1)
+    doc.add_heading('1、土地利用类型与检测指标符合性审核', level=2)
+    # 插入表格1
+    paragraph_1 = doc.add_paragraph()
+    paragraph_1.add_run(f"表1:{areaName}三普样品数量统计表(表层)").bold = True
+    # 设置居中
+    paragraph_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_1 = doc.add_table(rows=lenNum_1 + 1, cols=3, style='Light Shading Accent 1')
+    table_1.alignment = WD_TABLE_ALIGNMENT.CENTER
+
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1.cell(2, 2).text = ''
+        table_1.cell(1, 2).merge(table_1.cell(2, 2))
+    ############test##############
+    doc.add_heading('2、指标名称与实际检测样品数量完整性审核', level=2)
+    # 插入表格2
+    paragraph_2 = doc.add_paragraph()
+    paragraph_2.add_run(f'表2:{areaName}指标名称与实际检测样品数量统计表').bold = True
+    table_2 = doc.add_table(rows=len(table_2_data) + 1, cols=3, style='Light Shading Accent 1')
+    paragraph_2.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_2.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_2_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_2_data.iloc[i - 1, j]))
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+    doc.add_heading('二、数据规范性审核', level=1)
+    doc.add_heading('1、数据填报规范性审核', level=2)
+    # 插入表3
+    paragraph_3 = doc.add_paragraph()
+    paragraph_3.add_run(f'表3:{areaName}土壤检测数据检测方法填报审核结果表').bold = True
+    # table_3 = doc.add_table(rows=2, cols=2)
+    paragraph_3.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_3.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据写不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:检测方法审核结果.xlsx', level=4)
+    doc.add_heading('2、数值修约规范性审核', level=2)
+    # 插入表4
+    paragraph_4 = doc.add_paragraph()
+    paragraph_4.add_run(f'表4:{areaName}土壤检测数据数值修约结果表').bold = True
+    # table_4 = doc.add_table(rows=2, cols=2)
+    paragraph_4.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_4.alignment = WD_TABLE_ALIGNMENT.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数值修约审核.xlsx', level=4)
+    # 填入数据 这里数据也放不下 嵌入链接
+
+    doc.add_heading('3、数据未检出的填报规范性审核', level=2)
+    # 插入表5
+    paragraph_5 = doc.add_paragraph()
+    paragraph_5.add_run(f'表5:{areaName}土壤检测数据未检出项填报审核结果表').bold = True
+    # table_5 = doc.add_table(rows=2, cols=2)
+    paragraph_5.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_5.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据也放不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据填报项审核结果.xlsx', level=4)
+    doc.add_heading('4、土壤质地填报规范性审核', level=2)
+    # 插入表6
+    paragraph_6 = doc.add_paragraph()
+    paragraph_6.add_run(f'表6:{areaName}土壤质地填报审核结果表').bold = True
+    table_6 = doc.add_table(rows=len(table_6_data) + 1, cols=4, style='Light Shading Accent 1')
+    paragraph_6.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_6.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 提取结果表中数据
+    # 写入数据 土壤质地类型不一致的数据提取出来
+    for i, row in enumerate(table_6.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_6_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_6_data.iloc[i - 1, j]))
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+    doc.add_heading('三、数据合理性审核', level=1)
+    doc.add_heading('1、阈值法审核', level=2)
+
+    # 插入表格
+    paragraph_7 = doc.add_paragraph()
+    paragraph_7.add_run(f'表7:{areaName}土壤检测数据超阈值样品统计表').bold = True
+    # table_7 = doc.add_table(rows=2, cols=2)
+    # paragraph_7.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_7.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 点击查看数据 这里也不一定写的下 最好是嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:超阈值样品统计表.xlsx', level=4)
+    # todo 合并所有数据 审核结果不为空的数据 写入表格保存到指定文件夹
+    doc.add_heading('2、极值法审核', level=2)
+    doc.add_heading('(1)pH', level=3)
+    # 插入ph分布图
+    if os.path.isfile(f'{mkdir_path}/PH值分布图.png'):
+        doc.add_picture(f'{mkdir_path}/PH值分布图.png', width=Inches(6.0))
+    paragraph_t_1 = doc.add_paragraph()
+    paragraph_t_1.add_run(f'图1:pH值分布情况').bold = True
+    paragraph_t_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 插入频度统计表
+    paragraph_8 = doc.add_paragraph()
+    paragraph_8.add_run('表8:pH数据统计表').bold = True
+    table_8 = doc.add_table(rows=6, cols=2, style='Light Shading Accent 1')
+    t_8 = table_8_data['频度分析']
+
+    t_8 = t_8.reset_index()
+    t_8.columns = ['指标', '数据']
+    paragraph_8.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_8.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_8.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(t_8.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(t_8.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # 插入异常数据提取表格 todo 这里数据多的话也可能写不下 最好是嵌入一下
+    if not table_8_data['异常数据'].empty:
+        paragraph_9 = doc.add_paragraph()
+        paragraph_9.add_run('表9:pH异常数据统计表').bold = True
+        table_9 = doc.add_table(rows=len(table_8_data['异常数据']) + 1, cols=6, style='Light Shading Accent 1')
+        t_9 = table_8_data['异常数据']
+
+        paragraph_9.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_9.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_9.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(t_9.columns[j]))
+                    r.font.bold = True
+                else:
+                    r = paragraph.add_run(str(t_9.iloc[i - 1, j]))
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    doc.add_heading('四、审核存疑数据', level=1)
+    paragraph_12 = doc.add_paragraph()
+    paragraph_12.add_run(f'表10:数据审核过程存疑数据一览表').bold = True
+    paragraph_12.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:物理指标数据审核过程存疑数据一览表.xlsx', level=4)
+    doc.add_heading('五、附表', level=1)
+    doc.add_heading('附表1:某区三普样品数量统计表(表层)', level=2)
+    # 插入附表1
+    table_1_f = doc.add_table(rows=lenNum_1 + 1, cols=3, style='Light Shading Accent 1')
+    table_1_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1_f.cell(2, 2).text = ''
+        table_1_f.cell(1, 2).merge(table_1_f.cell(2, 2))
+
+    doc.add_heading('附表2:各指标频度分析表', level=2)
+    # 插入表格 写入数据
+    table_f_2_data = table_f_2_data.replace(np.nan, '')
+    makeInfoTable(table_f_2_data, doc)
+    # table_f_2 = doc.add_table(rows=len(table_f_2_data) + 1, cols=6, style='Light Shading Accent 1')
+    # for i, row in enumerate(table_f_2.rows):
+    #     for j, cell in enumerate(row.cells):
+    #         # 获取单元格中的段落对象
+    #         paragraph = cell.paragraphs[0]
+    #         if i == 0:
+    #             r = paragraph.add_run(str(table_f_2_data.columns[j]))
+    #             r.font.bold = True
+    #         else:
+    #             r = paragraph.add_run(str(table_f_2_data.iloc[i - 1, j]))
+    #         r.font.size = Pt(10.5)
+    #         r.font.name = 'Times New Roman'
+    #         r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    #         paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+    #         paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+    #         paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:频度分析表.xlsx', level=4)
+    doc.add_heading('附表3:各指标频度分析图', level=2)
+    # 插入频度信息的图形
+    if os.path.isfile(f'{mkdir_path}/0.002mm以下颗粒含量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/0.002mm以下颗粒含量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/0.02~0.002mm颗粒含量分析图.png.png'):
+        doc.add_picture(f'{mkdir_path}/0.02~0.002mm颗粒含量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/0.2~0.02mm颗粒含量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/0.2~0.02mm颗粒含量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/2~0.2mm颗粒含量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/2~0.2mm颗粒含量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/pH分析图.png'):
+        doc.add_picture(f'{mkdir_path}/pH分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/风干试样含水量(分析基)分析图.png'):
+        doc.add_picture(f'{mkdir_path}/风干试样含水量(分析基)分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/洗失量(吸管法需填)分析图.png'):
+        doc.add_picture(f'{mkdir_path}/洗失量(吸管法需填)分析图.png', width=Inches(6.0))
+
+    if os.path.isfile(f'{mkdir_path}/土壤容重1分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重1分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重2分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重2分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重3分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重3分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重4分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重4分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重平均值分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重平均值分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳0.5mm~1mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳0.5mm~1mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳0.25mm~0.5mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳0.25mm~0.5mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳1mm~2mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳1mm~2mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳2mm~3mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳2mm~3mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳3mm~5mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳3mm~5mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳5mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳5mm分析图.png', width=Inches(6.0))
+    doc.add_heading('附表4:数值修约标准', level=2)
+    # 读取数据 插入表格 写入数据
+    numData = pd.read_excel('./img/数值修约要求.xlsx', sheet_name='Sheet1')
+    table_2_f = doc.add_table(rows=len(numData) + 1, cols=2, style='Light Shading Accent 1')
+    table_2_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(numData.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(numData.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 处理样式 遍历所有的段落 修改字体
+    # 遍历并打印每个段落的文本
+    paragraphs = doc.paragraphs
+    for paragraph in paragraphs:
+        for run in paragraph.runs:
+            run.font.color.rgb = RGBColor(0, 0, 0)
+            run.font.name = 'Times New Roman'
+            run.font.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    # 保存Word文档
+
+    doc.save(f'{mkdir_path}/{areaName}-{type}审核报告.docx')
+
+# 生成常规养分指标审核报告
+def getConventionalNutrientIndicators(data,type, changeFileUrl, saveFileUrl, check_1_data,
+    check_3_data,
+    check_5_data,
+    check_8_data,  # 样品编号替换为编号
+    check_10_data,
+    check_12_data,
+    check_14_data ):
+    # 生成报告
+    name = os.path.basename(changeFileUrl)
+    n = name.split('.')
+    areaName = n[0].replace('数据', '')
+    # 生成一个新的文件夹用于存放审核报告相关的数据
+    nowTime = time.strftime("%Y-%m-%d %H时%M分%S秒", time.localtime())
+    dir_name = f'{areaName}-{type}数据审核报告'
+    mkdir_path = saveFileUrl + '/' + dir_name + nowTime
+    if not os.path.exists(mkdir_path):
+        os.mkdir(mkdir_path)
+    # 根据选择的路径读取数据
+    ConventionalNutrientData = data[indexClassificationList[type]]
+    report.getFrequencyImage(ConventionalNutrientData, mkdir_path)
+    ConventionalNutrientData['序号'] = data['序号']
+    ConventionalNutrientData['原样品编号'] = data['原样品编号']
+    ConventionalNutrientData['样品编号'] = data['样品编号']
+    ConventionalNutrientData['地理位置'] = data['地理位置']
+    ConventionalNutrientData['母质'] = data['母质']
+    ConventionalNutrientData['土壤类型'] = data['土壤类型']
+    ConventionalNutrientData['土地利用类型'] = data['土地利用类型']
+    # ConventionalNutrientData['土壤质地'] = data['土壤质地']
+    # 生成相应审核报告
+    ConventionalNutrientData['原样品编号'] = ConventionalNutrientData['原样品编号'].astype(str)
+    data['原样品编号'] = data['原样品编号'].astype(str)
+    # checkData = pd.read_excel(changeFileUrl, sheet_name='检测方法')
+
+    # 上面这个地址,可以纯递给函数中,用于保存表格和图片
+    # 调用函数 开始生成报告相关内容
+    # 表1相关数据
+    typeData = report.getSimpleNum(ConventionalNutrientData)
+    lenNum_1 = len(typeData['sData'])
+    lenNum_1_f = len(typeData['allData'])
+    table_1_data = pd.DataFrame({
+        '类型': typeData['sData'].index,
+        '数量': typeData['sData'],
+        '合计': [typeData['sData'].sum() for _ in range(lenNum_1)]
+    })
+
+    # 表2数据
+    table_2_data = report.getDataComplete(ConventionalNutrientData)
+    table_2_data = table_2_data.reset_index()
+    table_2_data.columns = ['指标名称', '实测数量', '应测数量']
+    # 表3数据
+    # table_3_data = report.checkMethod(checkData, mkdir_path)
+    # 数据修约 表4
+    report.getNum(ConventionalNutrientData, mkdir_path)
+    # 数据填报项审核 表5
+    report.dataReportResult(ConventionalNutrientData, mkdir_path)
+    # 表6数据 土壤质地类型不一致
+    middData = data[['原样品编号', '样品编号']].astype(str)
+    middData['编号'] = middData['原样品编号']
+    del middData['原样品编号']
+    check_1_data = pd.merge(check_1_data, middData, how='left', on='编号')
+    check_1_data = check_1_data.replace(np.nan, '')
+    # typeNotSame = check_1_data[check_1_data['土壤质地'] != check_1_data['土壤类型(判断)']]
+    # table_6_data = typeNotSame[['编号', '样品编号', '土壤质地', '土壤类型(判断)']]
+    allNeedData = pd.DataFrame({})
+    allNeedData['原样品编号'] = check_1_data['编号']
+    getSimpleDataNumber = pd.merge(allNeedData, ConventionalNutrientData[['原样品编号', '样品编号']], how='left', on="原样品编号")
+    allNeedData['样品编号'] = getSimpleDataNumber['样品编号']
+    allNeedData['土地利用类型'] = check_1_data['土地利用类型']
+    allNeedData['审核结果'] = check_10_data['审核结果'] + check_12_data['审核结果']
+    allNeedData['外业'] = ['' for _ in range(len(check_1_data))]
+    table_7_data = allNeedData[allNeedData['审核结果'] != '']
+    del table_7_data['审核结果']
+    # 写进表格
+    with pd.ExcelWriter(f'{mkdir_path}/超阈值样品统计表.xlsx', engine='openpyxl') as writer:
+        table_7_data.to_excel(writer, index=False, sheet_name='超阈值数据')
+
+    # 表8数据
+    table_8_data = report.getPHData(ConventionalNutrientData, mkdir_path)
+
+    # 表10 数据
+    table_10_data = report.getNAndC(ConventionalNutrientData, mkdir_path)
+
+    # 表11 数据:全磷和有效磷异常数据统计
+    table_11_data = report.getPData(ConventionalNutrientData, mkdir_path)
+
+    report.getKData(ConventionalNutrientData, mkdir_path)
+
+    # 表13 所有存疑数据
+    with pd.ExcelWriter(f'{mkdir_path}/数据审核过程存疑数据一览表.xlsx', engine='openpyxl') as writer:
+        allNeedData[allNeedData['审核结果'] != ''].to_excel(writer, index=False, sheet_name='存疑数据')
+    # 附表: 频度分析图
+    # report.getFrequencyImage(ConventionalNutrientData, mkdir_path)
+    table_f_2_data = report.getFrequencyInformation(data, mkdir_path)
+    # 新建一个文档
+    doc = Document()
+    # 添加标题
+    doc.add_heading(f"{areaName}第三次全国土壤普查数据审核报告", level=0)
+    # 添加一级标题
+    doc.add_heading('一、数据完整性审核', level=1)
+    doc.add_heading('1、土地利用类型与检测指标符合性审核', level=2)
+    # 插入表格1
+    paragraph_1 = doc.add_paragraph()
+    paragraph_1.add_run(f"表1:{areaName}三普样品数量统计表(表层)").bold = True
+    # 设置居中
+    paragraph_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_1 = doc.add_table(rows=lenNum_1 + 1, cols=3, style='Light Shading Accent 1')
+    table_1.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1.cell(2, 2).text = ''
+        table_1.cell(1, 2).merge(table_1.cell(2, 2))
+    ############test##############
+    doc.add_heading('2、指标名称与实际检测样品数量完整性审核', level=2)
+    # 插入表格2
+    paragraph_2 = doc.add_paragraph()
+    paragraph_2.add_run(f'表2:{areaName}指标名称与实际检测样品数量统计表').bold = True
+    table_2 = doc.add_table(rows=len(table_2_data) + 1, cols=3, style='Light Shading Accent 1')
+    paragraph_2.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_2.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_2_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_2_data.iloc[i - 1, j]))
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+    doc.add_heading('二、数据规范性审核', level=1)
+    doc.add_heading('1、数据填报规范性审核', level=2)
+    # 插入表3
+    paragraph_3 = doc.add_paragraph()
+    paragraph_3.add_run(f'表3:{areaName}土壤检测数据检测方法填报审核结果表').bold = True
+    # table_3 = doc.add_table(rows=2, cols=2)
+    paragraph_3.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_3.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据写不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:检测方法审核结果.xlsx', level=4)
+    doc.add_heading('2、数值修约规范性审核', level=2)
+    # 插入表4
+    paragraph_4 = doc.add_paragraph()
+    paragraph_4.add_run(f'表4:{areaName}土壤检测数据数值修约结果表').bold = True
+    # table_4 = doc.add_table(rows=2, cols=2)
+    paragraph_4.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_4.alignment = WD_TABLE_ALIGNMENT.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数值修约审核.xlsx', level=4)
+    # 填入数据 这里数据也放不下 嵌入链接
+
+    doc.add_heading('3、数据未检出的填报规范性审核', level=2)
+    # 插入表5
+    paragraph_5 = doc.add_paragraph()
+    paragraph_5.add_run(f'表5:{areaName}土壤检测数据未检出项填报审核结果表').bold = True
+    # table_5 = doc.add_table(rows=2, cols=2)
+    paragraph_5.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_5.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据也放不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据填报项审核结果.xlsx', level=4)
+    # doc.add_heading('4、土壤质地填报规范性审核', level=2)
+    # # 插入表6
+    # paragraph_6 = doc.add_paragraph()
+    # paragraph_6.add_run(f'表6:{areaName}土壤质地填报审核结果表').bold = True
+    # table_6 = doc.add_table(rows=len(table_6_data) + 1, cols=4, style='Light Shading Accent 1')
+    # paragraph_6.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_6.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # # 提取结果表中数据
+    # # 写入数据 土壤质地类型不一致的数据提取出来
+    # for i, row in enumerate(table_6.rows):
+    #     for j, cell in enumerate(row.cells):
+    #         # 获取单元格中的段落对象
+    #         paragraph = cell.paragraphs[0]
+    #         if i == 0:
+    #             r = paragraph.add_run(str(table_6_data.columns[j]))
+    #             r.font.bold = True
+    #         else:
+    #             r = paragraph.add_run(str(table_6_data.iloc[i - 1, j]))
+    #         paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+    #         paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+    #         paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    #         r.font.size = Pt(10.5)
+    #         r.font.name = 'Times New Roman'
+    #         r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+    doc.add_heading('三、数据合理性审核', level=1)
+    doc.add_heading('1、阈值法审核', level=2)
+
+    # 插入表格
+    paragraph_7 = doc.add_paragraph()
+    paragraph_7.add_run(f'表6:{areaName}土壤检测数据超阈值样品统计表').bold = True
+    # table_7 = doc.add_table(rows=2, cols=2)
+    # paragraph_7.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_7.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 点击查看数据 这里也不一定写的下 最好是嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据审核过程存疑数据一览表.xlsx', level=4)
+    # todo 合并所有数据 审核结果不为空的数据 写入表格保存到指定文件夹
+    doc.add_heading('2、极值法审核', level=2)
+    doc.add_heading('(1)pH', level=3)
+    # 插入ph分布图
+    if os.path.isfile(f'{mkdir_path}/PH值分布图.png'):
+        doc.add_picture(f'{mkdir_path}/PH值分布图.png', width=Inches(6.0))
+    paragraph_t_1 = doc.add_paragraph()
+    paragraph_t_1.add_run(f'图1:pH值分布情况').bold = True
+    paragraph_t_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 插入频度统计表
+    paragraph_8 = doc.add_paragraph()
+    paragraph_8.add_run('表7:pH数据统计表').bold = True
+    table_8 = doc.add_table(rows=6, cols=2, style='Light Shading Accent 1')
+    t_8 = table_8_data['频度分析']
+
+    t_8 = t_8.reset_index()
+    t_8.columns = ['指标', '数据']
+    paragraph_8.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_8.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_8.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(t_8.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(t_8.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # 插入异常数据提取表格 todo 这里数据多的话也可能写不下 最好是嵌入一下
+    if not table_8_data['异常数据'].empty:
+        paragraph_9 = doc.add_paragraph()
+        paragraph_9.add_run('表8:pH异常数据统计表').bold = True
+        table_9 = doc.add_table(rows=len(table_8_data['异常数据']) + 1, cols=6, style='Light Shading Accent 1')
+        t_9 = table_8_data['异常数据']
+
+        paragraph_9.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_9.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_9.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(t_9.columns[j]))
+                    r.font.bold = True
+                else:
+                    r = paragraph.add_run(str(t_9.iloc[i - 1, j]))
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    doc.add_heading('3、关联分析法审核', level=2)
+    if os.path.isfile(f'{mkdir_path}/有机质与全氮相关性分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有机质与全氮相关性分析图.png', width=Inches(6.0))
+    paragraph_t_2 = doc.add_paragraph()
+    paragraph_t_2.add_run(f'图2:有机质与全氮相关关系').bold = True
+    paragraph_t_2.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 插入碳氮比异常数据
+    if not table_10_data.empty:
+        paragraph_10 = doc.add_paragraph()
+        paragraph_10.add_run('表9:碳氮比异常数据统计表').bold = True
+        table_10 = doc.add_table(rows=len(table_10_data) + 1, cols=8, style='Light Shading Accent 1')
+        paragraph_10.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_10.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_10.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(table_10_data.columns[j]))
+                    r.font.bold = True
+                else:
+                    r = paragraph.add_run(str(table_10_data.iloc[i - 1, j]))
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    doc.add_heading('4、指标综合分析', level=2)
+    # 插入图片
+    if os.path.isfile(f'{mkdir_path}/全磷分布图.png'):
+        doc.add_picture(f'{mkdir_path}/全磷分布图.png', width=Inches(6.0))
+    paragraph_t_3 = doc.add_paragraph()
+    paragraph_t_3.add_run(f'图3:全磷分布图').bold = True
+    paragraph_t_3.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/有效磷分布图.png'):
+        doc.add_picture(f'{mkdir_path}/有效磷分布图.png', width=Inches(6.0))
+    paragraph_t_4 = doc.add_paragraph()
+    paragraph_t_4.add_run(f'图4:有效磷分布图').bold = True
+    paragraph_t_4.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 插入图片
+    if os.path.isfile(f'{mkdir_path}/有效磷占全磷比分布图.png'):
+        doc.add_picture(f'{mkdir_path}/有效磷占全磷比分布图.png', width=Inches(6.0))
+    paragraph_t_5 = doc.add_paragraph()
+    paragraph_t_5.add_run(f'图5:有效磷含量占全磷含量比例').bold = True
+    paragraph_t_5.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 插入表格
+    if not table_11_data.empty:
+        paragraph_11 = doc.add_paragraph()
+        paragraph_11.add_run('表10:全磷与有效磷异常样品统计表').bold = True
+        table_11 = doc.add_table(rows=len(table_11_data) + 1, cols=7, style='Light Shading Accent 1')
+        paragraph_11.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_11.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_11.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(table_11_data.columns[j]))
+                    r.font.bold = True
+                else:
+                    r = paragraph.add_run(str(table_11_data.iloc[i - 1, j]))
+
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    else:
+        paragraph_11 = doc.add_paragraph()
+        paragraph_11.add_run('表10:全磷与有效磷异常样品统计表').bold = True
+        paragraph_11_info = doc.add_paragraph()
+        paragraph_11_info.add_run('无异常数据')
+        paragraph_11.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        paragraph_11_info.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # 全钾、速效钾、缓效钾
+    if os.path.isfile(f'{mkdir_path}/全钾与速效钾缓效钾之和关系统计图.png'):
+        doc.add_picture(f'{mkdir_path}/全钾与速效钾缓效钾之和关系统计图.png', width=Inches(6.0))
+    paragraph_t_6 = doc.add_paragraph()
+    paragraph_t_6.add_run(f'图6:全钾与速效钾缓效钾之和关系统计图').bold = True
+    paragraph_t_6.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/速效钾与缓效钾关系统计图.png'):
+        doc.add_picture(f'{mkdir_path}/速效钾与缓效钾关系统计图.png', width=Inches(6.0))
+    paragraph_t_7 = doc.add_paragraph()
+    paragraph_t_7.add_run(f'图7:速效钾与缓效钾关系统计图').bold = True
+    paragraph_t_7.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    doc.add_heading('四、审核存疑数据', level=1)
+    paragraph_12 = doc.add_paragraph()
+    paragraph_12.add_run(f'表11:数据审核过程存疑数据一览表').bold = True
+    paragraph_12.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据审核过程存疑数据一览表.xlsx', level=4)
+    doc.add_heading('五、附表', level=1)
+    doc.add_heading('附表1:某区三普样品数量统计表(表层)', level=2)
+    # 插入附表1
+    table_1_f = doc.add_table(rows=lenNum_1 + 1, cols=3, style='Light Shading Accent 1')
+    table_1_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1_f.cell(2, 2).text = ''
+        table_1_f.cell(1, 2).merge(table_1_f.cell(2, 2))
+
+    doc.add_heading('附表2:各指标频度分析表', level=2)
+    # 插入表格 写入数据
+    table_f_2_data = table_f_2_data.replace(np.nan, '')
+    makeInfoTable(table_f_2_data, doc)
+    # table_f_2 = doc.add_table(rows=len(table_f_2_data) + 1, cols=6, style='Light Shading Accent 1')
+    # for i, row in enumerate(table_f_2.rows):
+    #     for j, cell in enumerate(row.cells):
+    #         # 获取单元格中的段落对象
+    #         paragraph = cell.paragraphs[0]
+    #         if i == 0:
+    #             r = paragraph.add_run(str(table_f_2_data.columns[j]))
+    #             r.font.bold = True
+    #         else:
+    #             r = paragraph.add_run(str(table_f_2_data.iloc[i - 1, j]))
+    #         r.font.size = Pt(10.5)
+    #         r.font.name = 'Times New Roman'
+    #         r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    #         paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+    #         paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+    #         paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:频度分析表.xlsx', level=4)
+    doc.add_heading('附表3:各指标频度分析图', level=2)
+    # 插入频度信息的图形
+
+    if os.path.isfile(f'{mkdir_path}/pH分析图.png'):
+        doc.add_picture(f'{mkdir_path}/pH分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/缓效钾分析图.png'):
+        doc.add_picture(f'{mkdir_path}/缓效钾分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/全氮分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全氮分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/全钾分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全钾分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/全磷分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全磷分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/速效钾分析图.png'):
+        doc.add_picture(f'{mkdir_path}/速效钾分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有机质分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有机质分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效硅分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效硅分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效磷分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效磷分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效硫分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效硫分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效锰分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效锰分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效钼分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效钼分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效硼分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效硼分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效铁分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效铁分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效铜分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效铜分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效锌分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效锌分析图.png', width=Inches(6.0))
+    doc.add_heading('附表4:数值修约标准', level=2)
+    # 读取数据 插入表格 写入数据
+    numData = pd.read_excel('./img/数值修约要求.xlsx', sheet_name='Sheet1')
+    table_2_f = doc.add_table(rows=len(numData) + 1, cols=2, style='Light Shading Accent 1')
+    table_2_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(numData.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(numData.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # 处理样式 遍历所有的段落 修改字体
+    # 遍历并打印每个段落的文本
+    paragraphs = doc.paragraphs
+    for paragraph in paragraphs:
+        for run in paragraph.runs:
+            run.font.color.rgb = RGBColor(0, 0, 0)
+            run.font.name = 'Times New Roman'
+            run.font.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    # 保存Word文档
+
+    doc.save(f'{mkdir_path}/{areaName}-{type}审核报告.docx')
+
+
+
+# 生成一般化学性指标审核报告
+def getChemicalIndicators(data,type, changeFileUrl, saveFileUrl, check_1_data,
+    check_3_data,
+    check_5_data,
+    check_8_data,  # 样品编号替换为编号
+    check_10_data,
+    check_12_data,
+    check_14_data):
+    # 生成报告
+    name = os.path.basename(changeFileUrl)
+    n = name.split('.')
+    areaName = n[0].replace('数据', '')
+    # 生成一个新的文件夹用于存放审核报告相关的数据
+    nowTime = time.strftime("%Y-%m-%d %H时%M分%S秒", time.localtime())
+    dir_name = f'{areaName}-{type}数据审核报告'
+    mkdir_path = saveFileUrl + '/' + dir_name + nowTime
+    if not os.path.exists(mkdir_path):
+        os.mkdir(mkdir_path)
+    # 根据选择的路径读取数据
+
+    cheemicalData = data[indexClassificationList[type]]
+    report.getFrequencyImage(cheemicalData, mkdir_path)
+    cheemicalData['序号'] = data['序号']
+    cheemicalData['原样品编号'] = data['原样品编号']
+    cheemicalData['样品编号'] = data['样品编号']
+    cheemicalData['地理位置'] = data['地理位置']
+    cheemicalData['母质'] = data['母质']
+    cheemicalData['土壤类型'] = data['土壤类型']
+    cheemicalData['土地利用类型'] = data['土地利用类型']
+    # cheemicalData['土壤质地'] = data['土壤质地']
+    cheemicalData['原样品编号'] = cheemicalData['原样品编号'].astype(str)
+    # checkData = pd.read_excel(changeFileUrl, sheet_name='检测方法')
+
+    # 上面这个地址,可以纯递给函数中,用于保存表格和图片
+    # 调用函数 开始生成报告相关内容
+    # 表1相关数据
+    typeData = report.getSimpleNum(cheemicalData)
+    lenNum_1 = len(typeData['sData'])
+    lenNum_1_f = len(typeData['allData'])
+    table_1_data = pd.DataFrame({
+        '类型': typeData['sData'].index,
+        '数量': typeData['sData'],
+        '合计': [typeData['sData'].sum() for _ in range(lenNum_1)]
+    })
+
+    # 表2数据
+    table_2_data = report.getDataComplete(cheemicalData)
+    table_2_data = table_2_data.reset_index()
+    table_2_data.columns = ['指标名称', '实测数量', '应测数量']
+    # 表3数据
+    # table_3_data = report.checkMethod(checkData, mkdir_path)
+    # 数据修约 表4
+    report.getNum(cheemicalData, mkdir_path)
+    # 数据填报项审核 表5
+    report.dataReportResult(cheemicalData, mkdir_path)
+    # 表6数据 土壤质地类型不一致
+    middData = data[['原样品编号', '样品编号']].astype(str)
+    middData['编号'] = middData['原样品编号']
+    del middData['原样品编号']
+    check_1_data = pd.merge(check_1_data, middData, how='left', on='编号')
+    check_1_data = check_1_data.replace(np.nan, '')
+    # typeNotSame = check_1_data[check_1_data['土壤质地'] != check_1_data['土壤类型(判断)']]
+    # table_6_data = typeNotSame[['编号', '样品编号', '土壤质地', '土壤类型(判断)']]
+    allNeedData = pd.DataFrame({})
+    allNeedData['原样品编号'] = check_1_data['编号']
+    getSimpleDataNumber = pd.merge(allNeedData, data[['原样品编号', '样品编号']], how='left', on="原样品编号")
+    allNeedData['样品编号'] = getSimpleDataNumber['样品编号']
+    allNeedData['土地利用类型'] = check_1_data['土地利用类型']
+    allNeedData['审核结果'] = check_5_data['审核结果'] + check_8_data['审核结果']
+    allNeedData['外业'] = ['' for _ in range(len(check_1_data))]
+    table_7_data = allNeedData[allNeedData['审核结果'] != '']
+    del table_7_data['审核结果']
+    # 写进表格
+    with pd.ExcelWriter(f'{mkdir_path}/超阈值样品统计表.xlsx', engine='openpyxl') as writer:
+        table_7_data.to_excel(writer, index=False, sheet_name='超阈值数据')
+
+    # 表8数据
+    table_8_data = report.getPHData(cheemicalData, mkdir_path)
+
+
+    report.cationExchangeCapacity(cheemicalData, mkdir_path)
+    report.changeCation(cheemicalData, mkdir_path)
+    report.manyTypes(cheemicalData, mkdir_path)
+
+    # 表13 所有存疑数据
+    with pd.ExcelWriter(f'{mkdir_path}/数据审核过程存疑数据一览表.xlsx', engine='openpyxl') as writer:
+        allNeedData[allNeedData['审核结果'] != ''].to_excel(writer, index=False, sheet_name='存疑数据')
+    # 附表: 频度分析图
+    # report.getFrequencyImage(cheemicalData, mkdir_path)
+    table_f_2_data = report.getFrequencyInformation(data, mkdir_path)
+    # 新建一个文档
+    doc = Document()
+    # 添加标题
+    doc.add_heading(f"{areaName}第三次全国土壤普查数据审核报告", level=0)
+    # 添加一级标题
+    doc.add_heading('一、数据完整性审核', level=1)
+    doc.add_heading('1、土地利用类型与检测指标符合性审核', level=2)
+
+    # 插入表格1
+    paragraph_1 = doc.add_paragraph()
+    paragraph_1.add_run(f"表1:{areaName}三普样品数量统计表(表层)").bold = True
+    # 设置居中
+    paragraph_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_1 = doc.add_table(rows=lenNum_1 + 1, cols=3, style='Light Shading Accent 1')
+    table_1.alignment = WD_TABLE_ALIGNMENT.CENTER
+
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1.cell(2, 2).text = ''
+        table_1.cell(1, 2).merge(table_1.cell(2, 2))
+
+
+    ############test##############
+    doc.add_heading('2、指标名称与实际检测样品数量完整性审核', level=2)
+    # 插入表格2
+    paragraph_2 = doc.add_paragraph()
+    paragraph_2.add_run(f'表2:{areaName}指标名称与实际检测样品数量统计表').bold = True
+    table_2 = doc.add_table(rows=len(table_2_data) + 1, cols=3, style='Light Shading Accent 1')
+    paragraph_2.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_2.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_2_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_2_data.iloc[i - 1, j]))
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+    doc.add_heading('二、数据规范性审核', level=1)
+    doc.add_heading('1、数据填报规范性审核', level=2)
+    # 插入表3
+    paragraph_3 = doc.add_paragraph()
+    paragraph_3.add_run(f'表3:{areaName}土壤检测数据检测方法填报审核结果表').bold = True
+    # table_3 = doc.add_table(rows=2, cols=2)
+    paragraph_3.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_3.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据写不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:检测方法审核结果.xlsx', level=4)
+    doc.add_heading('2、数值修约规范性审核', level=2)
+    # 插入表4
+    paragraph_4 = doc.add_paragraph()
+    paragraph_4.add_run(f'表4:{areaName}土壤检测数据数值修约结果表').bold = True
+    # table_4 = doc.add_table(rows=2, cols=2)
+    paragraph_4.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_4.alignment = WD_TABLE_ALIGNMENT.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数值修约审核.xlsx', level=4)
+    # 填入数据 这里数据也放不下 嵌入链接
+
+    doc.add_heading('3、数据未检出的填报规范性审核', level=2)
+    # 插入表5
+    paragraph_5 = doc.add_paragraph()
+    paragraph_5.add_run(f'表5:{areaName}土壤检测数据未检出项填报审核结果表').bold = True
+    # table_5 = doc.add_table(rows=2, cols=2)
+    paragraph_5.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_5.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据也放不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据填报项审核结果.xlsx', level=4)
+    # doc.add_heading('4、土壤质地填报规范性审核', level=2)
+    # # 插入表6
+    # paragraph_6 = doc.add_paragraph()
+    # paragraph_6.add_run(f'表6:{areaName}土壤质地填报审核结果表').bold = True
+    # table_6 = doc.add_table(rows=len(table_6_data) + 1, cols=4, style='Light Shading Accent 1')
+    # paragraph_6.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_6.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # # 提取结果表中数据
+    # # 写入数据 土壤质地类型不一致的数据提取出来
+    # for i, row in enumerate(table_6.rows):
+    #     for j, cell in enumerate(row.cells):
+    #         # 获取单元格中的段落对象
+    #         paragraph = cell.paragraphs[0]
+    #         if i == 0:
+    #             r = paragraph.add_run(str(table_6_data.columns[j]))
+    #             r.font.bold = True
+    #         else:
+    #             r = paragraph.add_run(str(table_6_data.iloc[i - 1, j]))
+    #         paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+    #         paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+    #         paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    #         r.font.size = Pt(10.5)
+    #         r.font.name = 'Times New Roman'
+    #         r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+    doc.add_heading('三、数据合理性审核', level=1)
+    doc.add_heading('1、阈值法审核', level=2)
+
+    # 插入表格
+    paragraph_7 = doc.add_paragraph()
+    paragraph_7.add_run(f'表6:{areaName}土壤检测数据超阈值样品统计表').bold = True
+    # table_7 = doc.add_table(rows=2, cols=2)
+    # paragraph_7.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_7.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 点击查看数据 这里也不一定写的下 最好是嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据审核过程存疑数据一览表.xlsx', level=4)
+    # todo 合并所有数据 审核结果不为空的数据 写入表格保存到指定文件夹
+    doc.add_heading('2、极值法审核', level=2)
+    doc.add_heading('(1)pH', level=3)
+    # 插入ph分布图
+    if os.path.isfile(f'{mkdir_path}/pH值分布图.png'):
+        doc.add_picture(f'{mkdir_path}/pH值分布图.png', width=Inches(6.0))
+    paragraph_t_1 = doc.add_paragraph()
+    paragraph_t_1.add_run(f'图1:pH值分布情况').bold = True
+    paragraph_t_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 插入频度统计表
+    paragraph_8 = doc.add_paragraph()
+    paragraph_8.add_run('表7:pH数据统计表').bold = True
+    table_8 = doc.add_table(rows=6, cols=2, style='Light Shading Accent 1')
+    t_8 = table_8_data['频度分析']
+
+    t_8 = t_8.reset_index()
+    t_8.columns = ['指标', '数据']
+    paragraph_8.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_8.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_8.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(t_8.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(t_8.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # 插入异常数据提取表格 todo 这里数据多的话也可能写不下 最好是嵌入一下
+    if not table_8_data['异常数据'].empty:
+        paragraph_9 = doc.add_paragraph()
+        paragraph_9.add_run('表8:pH异常数据统计表').bold = True
+        table_9 = doc.add_table(rows=len(table_8_data['异常数据']) + 1, cols=6, style='Light Shading Accent 1')
+        t_9 = table_8_data['异常数据']
+
+        paragraph_9.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_9.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_9.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(t_9.columns[j]))
+                    r.font.bold = True
+                else:
+                    r = paragraph.add_run(str(t_9.iloc[i - 1, j]))
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+
+
+    doc.add_heading('3、指标综合分析', level=2)
+
+    # 阳离子交换量与交换性盐总量关系
+    if os.path.isfile(f'{mkdir_path}/阳离子交换量与交换性盐基总量相关关系.png'):
+        doc.add_picture(f'{mkdir_path}/阳离子交换量与交换性盐基总量相关关系.png', width=Inches(6.0))
+    paragraph_t_8 = doc.add_paragraph()
+    paragraph_t_8.add_run(f'图8:阳离子交换量与交换性盐总量关系图').bold = True
+    paragraph_t_8.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 交换性盐总量与交换性盐相关关系
+    if os.path.isfile(f'{mkdir_path}/交换性盐基总量与交换性盐相关关系(pH小于等于7.5).png'):
+        doc.add_picture(f'{mkdir_path}/交换性盐基总量与交换性盐相关关系(pH小于等于7.5).png', width=Inches(6.0))
+    paragraph_t_9 = doc.add_paragraph()
+    paragraph_t_9.add_run(f'图9:交换性盐基总量和交换性钙镁钠钾分项指标关系(pH≤7.5)').bold = True
+    paragraph_t_9.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/交换性盐基总量与交换性盐相关关系(pH大于7.5).png'):
+        doc.add_picture(f'{mkdir_path}/交换性盐基总量与交换性盐相关关系(pH大于7.5).png', width=Inches(6.0))
+    paragraph_t_10 = doc.add_paragraph()
+    paragraph_t_10.add_run(f'图10:交换性盐基总量和交换性钙镁钠钾分项指标关系(pH大于7.5)').bold = True
+    paragraph_t_10.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 水溶性盐、电导率、离子总量
+    if os.path.isfile(f'{mkdir_path}/全盐量分布图.png'):
+        doc.add_picture(f'{mkdir_path}/全盐量分布图.png', width=Inches(6.0))
+    paragraph_t_11 = doc.add_paragraph()
+    paragraph_t_11.add_run(f'图11:全盐量分布图').bold = True
+    paragraph_t_11.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/全盐量与电导率相关性分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全盐量与电导率相关性分析图.png', width=Inches(6.0))
+    paragraph_t_12 = doc.add_paragraph()
+    paragraph_t_12.add_run(f'图12:全盐量与电导率相关性分析图').bold = True
+    paragraph_t_12.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/离子总量与水溶性盐总量关系图.png'):
+        doc.add_picture(f'{mkdir_path}/离子总量与水溶性盐总量关系图.png', width=Inches(6.0))
+    paragraph_t_13 = doc.add_paragraph()
+    paragraph_t_13.add_run(f'图13:水溶性盐总量与离子总量关系分析图').bold = True
+    paragraph_t_13.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    doc.add_heading('四、审核存疑数据', level=1)
+    paragraph_12 = doc.add_paragraph()
+    paragraph_12.add_run(f'表9:数据审核过程存疑数据一览表').bold = True
+    paragraph_12.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据审核过程存疑数据一览表.xlsx', level=4)
+    doc.add_heading('五、附表', level=1)
+    doc.add_heading('附表1:某区三普样品数量统计表(表层)', level=2)
+    # 插入附表1
+    table_1_f = doc.add_table(rows=lenNum_1 + 1, cols=3, style='Light Shading Accent 1')
+    table_1_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1_f.cell(2, 2).text = ''
+        table_1_f.cell(1, 2).merge(table_1_f.cell(2, 2))
+
+    doc.add_heading('附表2:各指标频度分析表', level=2)
+    # 插入表格 写入数据
+    table_f_2_data = table_f_2_data.replace(np.nan, '')
+    makeInfoTable(table_f_2_data, doc)
+    # table_f_2 = doc.add_table(rows=len(table_f_2_data) + 1, cols=6, style='Light Shading Accent 1')
+    # for i, row in enumerate(table_f_2.rows):
+    #     for j, cell in enumerate(row.cells):
+    #         # 获取单元格中的段落对象
+    #         paragraph = cell.paragraphs[0]
+    #         if i == 0:
+    #             r = paragraph.add_run(str(table_f_2_data.columns[j]))
+    #             r.font.bold = True
+    #         else:
+    #             r = paragraph.add_run(str(table_f_2_data.iloc[i - 1, j]))
+    #         r.font.size = Pt(10.5)
+    #         r.font.name = 'Times New Roman'
+    #         r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    #         paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+    #         paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+    #         paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:频度分析表.xlsx', level=4)
+    doc.add_heading('附表3:各指标频度分析图', level=2)
+    # 插入频度信息的图形
+
+    if os.path.isfile(f'{mkdir_path}/pH分析图.png'):
+        doc.add_picture(f'{mkdir_path}/pH分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/电导率分析图.png'):
+        doc.add_picture(f'{mkdir_path}/电导率分析图.png', width=Inches(6.0))
+
+    if os.path.isfile(f'{mkdir_path}/交换性钙分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性钙分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性钾分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性钾分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性镁分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性镁分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性钠分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性钠分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性盐基总量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性盐基总量分析图.png', width=Inches(6.0))
+
+    if os.path.isfile(f'{mkdir_path}/全盐量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全盐量分析图.png', width=Inches(6.0))
+
+    if os.path.isfile(f'{mkdir_path}/阳离子交换量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/阳离子交换量分析图.png', width=Inches(6.0))
+
+    doc.add_heading('附表4:数值修约标准', level=2)
+    # 读取数据 插入表格 写入数据
+    numData = pd.read_excel('./img/数值修约要求.xlsx', sheet_name='Sheet1')
+    table_2_f = doc.add_table(rows=len(numData) + 1, cols=2, style='Light Shading Accent 1')
+    table_2_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(numData.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(numData.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # 处理样式 遍历所有的段落 修改字体
+    # 遍历并打印每个段落的文本
+    paragraphs = doc.paragraphs
+    for paragraph in paragraphs:
+        for run in paragraph.runs:
+            run.font.color.rgb = RGBColor(0, 0, 0)
+            run.font.name = 'Times New Roman'
+            run.font.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+            # run.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    # 保存Word文档
+
+    doc.save(f'{mkdir_path}/{areaName}审核报告.docx')
+
+# 生成重金属指标审核报告
+def getHeavyMetalIndicators(data, type, changeFileUrl, saveFileUrl, check_1_data,
+    check_3_data,
+    check_5_data,
+    check_8_data,  # 样品编号替换为编号
+    check_10_data,
+    check_12_data,
+    check_14_data):
+    # 生成报告
+    name = os.path.basename(changeFileUrl)
+    n = name.split('.')
+    areaName = n[0].replace('数据', '')
+    # 生成一个新的文件夹用于存放审核报告相关的数据
+    nowTime = time.strftime("%Y-%m-%d %H时%M分%S秒", time.localtime())
+    dir_name = f'{areaName}-{type}数据审核报告'
+    mkdir_path = saveFileUrl + '/' + dir_name + nowTime
+    if not os.path.exists(mkdir_path):
+        os.mkdir(mkdir_path)
+    heavyMetaData = data[indexClassificationList[type]]
+    report.getFrequencyImage(heavyMetaData, mkdir_path)
+    heavyMetaData['序号'] = data['序号']
+    heavyMetaData['原样品编号'] = data['原样品编号']
+    heavyMetaData['样品编号'] = data['样品编号']
+    heavyMetaData['地理位置'] = data['地理位置']
+    heavyMetaData['母质'] = data['母质']
+    heavyMetaData['土壤类型'] = data['土壤类型']
+    heavyMetaData['土地利用类型'] = data['土地利用类型']
+    # heavyMetaData['土壤质地'] = data['土壤质地']
+    heavyMetaData['原样品编号'] = heavyMetaData['原样品编号'].astype(str)
+    # checkData = pd.read_excel(changeFileUrl, sheet_name='检测方法')
+
+    # 上面这个地址,可以纯递给函数中,用于保存表格和图片
+    # 调用函数 开始生成报告相关内容
+    # 表1相关数据
+    typeData = report.getSimpleNum(heavyMetaData)
+    lenNum_1 = len(typeData['sData'])
+    lenNum_1_f = len(typeData['allData'])
+    table_1_data = pd.DataFrame({
+        '类型': typeData['sData'].index,
+        '数量': typeData['sData'],
+        '合计': [typeData['sData'].sum() for _ in range(lenNum_1)]
+    })
+
+    # 表2数据
+    table_2_data = report.getDataComplete(heavyMetaData)
+    table_2_data = table_2_data.reset_index()
+    table_2_data.columns = ['指标名称', '实测数量', '应测数量']
+    # 表3数据
+    # table_3_data = report.checkMethod(checkData, mkdir_path)
+    # 数据修约 表4
+    report.getNum(heavyMetaData, mkdir_path)
+    # 数据填报项审核 表5
+    report.dataReportResult(heavyMetaData, mkdir_path)
+    # 表6数据 土壤质地类型不一致
+    middData = heavyMetaData[['原样品编号', '样品编号']].astype(str)
+    middData['编号'] = middData['原样品编号']
+    del middData['原样品编号']
+    check_1_data = pd.merge(check_1_data, middData, how='left', on='编号')
+    check_1_data = check_1_data.replace(np.nan, '')
+    # typeNotSame = check_1_data[check_1_data['土壤质地'] != check_1_data['土壤类型(判断)']]
+    # table_6_data = typeNotSame[['编号', '样品编号', '土壤质地', '土壤类型(判断)']]
+
+
+    allNeedData = pd.DataFrame({})
+    allNeedData['原样品编号'] = check_1_data['编号']
+    getSimpleDataNumber = pd.merge(allNeedData, heavyMetaData[['原样品编号', '样品编号']], how='left', on="原样品编号")
+    allNeedData['样品编号'] = getSimpleDataNumber['样品编号']
+    allNeedData['土地利用类型'] = check_1_data['土地利用类型']
+    allNeedData['审核结果'] = check_14_data['审核结果']
+    allNeedData['外业'] = ['' for _ in range(len(check_1_data))]
+    table_7_data = allNeedData[allNeedData['审核结果'] != '']
+    del table_7_data['审核结果']
+    # 写进表格
+    with pd.ExcelWriter(f'{mkdir_path}/超阈值样品统计表.xlsx', engine='openpyxl') as writer:
+        table_7_data.to_excel(writer, index=False, sheet_name='超阈值数据')
+
+    # 表8数据
+    table_8_data = report.getPHData(heavyMetaData, mkdir_path)
+
+
+    # 表12数据 重金属超标
+    caOverData = pd.merge(check_1_data[['编号', '土地利用类型']], check_14_data[
+        ['编号', 'pH', '镉mg/kg', '汞mg/kg', '砷mg/kg', '铅mg/kg', '铬mg/kg', '镍mg/kg', '审核结果']], how='outer',
+                          on=['编号'])
+    caOverData['原样品编号'] = caOverData['编号']
+    caOverData = pd.merge(caOverData, heavyMetaData[['原样品编号', '样品编号']], how='left', on='原样品编号')
+    first_column = caOverData.pop('样品编号')
+    caOverData.insert(0, '样品编号', first_column)
+    caOverData_need = caOverData[caOverData['审核结果'] != '']
+
+    # 写进表格
+    with pd.ExcelWriter(f'{mkdir_path}/重金属超筛选值情况统计.xlsx', engine='openpyxl') as writer:
+        caOverData_need.to_excel(writer, index=False, sheet_name='重金属超筛选值情况统计')
+
+    # 表13 所有存疑数据
+    with pd.ExcelWriter(f'{mkdir_path}/数据审核过程存疑数据一览表.xlsx', engine='openpyxl') as writer:
+        allNeedData[allNeedData['审核结果'] != ''].to_excel(writer, index=False, sheet_name='存疑数据')
+    # 附表: 频度分析图
+    # report.getFrequencyImage(heavyMetaData, mkdir_path)
+    table_f_2_data = report.getFrequencyInformation(data, mkdir_path)
+    # 新建一个文档
+    doc = Document()
+    # 添加标题
+    doc.add_heading(f"{areaName}第三次全国土壤普查数据审核报告", level=0)
+    # 添加一级标题
+    doc.add_heading('一、数据完整性审核', level=1)
+    doc.add_heading('1、土地利用类型与检测指标符合性审核', level=2)
+    # 插入表格1
+    paragraph_1 = doc.add_paragraph()
+    paragraph_1.add_run(f"表1:{areaName}三普样品数量统计表(表层)").bold = True
+    # 设置居中
+    paragraph_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_1 = doc.add_table(rows=lenNum_1 + 1, cols=3, style='Light Shading Accent 1')
+    table_1.alignment = WD_TABLE_ALIGNMENT.CENTER
+
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1.cell(2, 2).text = ''
+        table_1.cell(1, 2).merge(table_1.cell(2, 2))
+
+    ############test##############
+    doc.add_heading('2、指标名称与实际检测样品数量完整性审核', level=2)
+    # 插入表格2
+    paragraph_2 = doc.add_paragraph()
+    paragraph_2.add_run(f'表2:{areaName}指标名称与实际检测样品数量统计表').bold = True
+    table_2 = doc.add_table(rows=len(table_2_data) + 1, cols=3, style='Light Shading Accent 1')
+    paragraph_2.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_2.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_2_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_2_data.iloc[i - 1, j]))
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+    doc.add_heading('二、数据规范性审核', level=1)
+    doc.add_heading('1、数据填报规范性审核', level=2)
+    # 插入表3
+    paragraph_3 = doc.add_paragraph()
+    paragraph_3.add_run(f'表3:{areaName}土壤检测数据检测方法填报审核结果表').bold = True
+    # table_3 = doc.add_table(rows=2, cols=2)
+    paragraph_3.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_3.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据写不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:检测方法审核结果.xlsx', level=4)
+    doc.add_heading('2、数值修约规范性审核', level=2)
+    # 插入表4
+    paragraph_4 = doc.add_paragraph()
+    paragraph_4.add_run(f'表4:{areaName}土壤检测数据数值修约结果表').bold = True
+    # table_4 = doc.add_table(rows=2, cols=2)
+    paragraph_4.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_4.alignment = WD_TABLE_ALIGNMENT.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数值修约审核.xlsx', level=4)
+    # 填入数据 这里数据也放不下 嵌入链接
+
+    doc.add_heading('3、数据未检出的填报规范性审核', level=2)
+    # 插入表5
+    paragraph_5 = doc.add_paragraph()
+    paragraph_5.add_run(f'表5:{areaName}土壤检测数据未检出项填报审核结果表').bold = True
+    # table_5 = doc.add_table(rows=2, cols=2)
+    paragraph_5.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_5.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据也放不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据填报项审核结果.xlsx', level=4)
+    # doc.add_heading('4、土壤质地填报规范性审核', level=2)
+    # 插入表6
+    # paragraph_6 = doc.add_paragraph()
+    # paragraph_6.add_run(f'表6:{areaName}土壤质地填报审核结果表').bold = True
+    # table_6 = doc.add_table(rows=len(table_6_data) + 1, cols=4, style='Light Shading Accent 1')
+    # paragraph_6.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_6.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # # 提取结果表中数据
+    # # 写入数据 土壤质地类型不一致的数据提取出来
+    # for i, row in enumerate(table_6.rows):
+    #     for j, cell in enumerate(row.cells):
+    #         # 获取单元格中的段落对象
+    #         paragraph = cell.paragraphs[0]
+    #         if i == 0:
+    #             r = paragraph.add_run(str(table_6_data.columns[j]))
+    #             r.font.bold = True
+    #         else:
+    #             r = paragraph.add_run(str(table_6_data.iloc[i - 1, j]))
+    #         paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+    #         paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+    #         paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    #         r.font.size = Pt(10.5)
+    #         r.font.name = 'Times New Roman'
+    #         r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+    doc.add_heading('三、数据合理性审核', level=1)
+    doc.add_heading('1、阈值法审核', level=2)
+
+    # 插入表格
+    paragraph_7 = doc.add_paragraph()
+    paragraph_7.add_run(f'表6:{areaName}土壤检测数据超阈值样品统计表').bold = True
+    # table_7 = doc.add_table(rows=2, cols=2)
+    # paragraph_7.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_7.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 点击查看数据 这里也不一定写的下 最好是嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据审核过程存疑数据一览表.xlsx', level=4)
+    # todo 合并所有数据 审核结果不为空的数据 写入表格保存到指定文件夹
+    doc.add_heading('2、极值法审核', level=2)
+    doc.add_heading('(1)pH', level=3)
+    # 插入ph分布图
+    if os.path.isfile(f'{mkdir_path}/pH值分布图.png'):
+        doc.add_picture(f'{mkdir_path}/pH值分布图.png', width=Inches(6.0))
+    paragraph_t_1 = doc.add_paragraph()
+    paragraph_t_1.add_run(f'图1:pH值分布情况').bold = True
+    paragraph_t_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 插入频度统计表
+    paragraph_8 = doc.add_paragraph()
+    paragraph_8.add_run('表7:pH数据统计表').bold = True
+    table_8 = doc.add_table(rows=6, cols=2, style='Light Shading Accent 1')
+    t_8 = table_8_data['频度分析']
+
+    t_8 = t_8.reset_index()
+    t_8.columns = ['指标', '数据']
+    paragraph_8.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_8.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_8.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(t_8.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(t_8.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # 插入异常数据提取表格 todo 这里数据多的话也可能写不下 最好是嵌入一下
+    if not table_8_data['异常数据'].empty:
+        paragraph_9 = doc.add_paragraph()
+        paragraph_9.add_run('表8:pH异常数据统计表').bold = True
+        table_9 = doc.add_table(rows=len(table_8_data['异常数据']) + 1, cols=6, style='Light Shading Accent 1')
+        t_9 = table_8_data['异常数据']
+
+        paragraph_9.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_9.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_9.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(t_9.columns[j]))
+                    r.font.bold = True
+                else:
+                    r = paragraph.add_run(str(t_9.iloc[i - 1, j]))
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+
+    doc.add_heading('4、指标综合分析', level=2)
+    doc.add_heading('表9:重金属超筛选值情况统计', level=4)
+    # todo 获取重金属数据
+
+
+    doc.add_heading('四、审核存疑数据', level=1)
+    paragraph_12 = doc.add_paragraph()
+    paragraph_12.add_run(f'表10:数据审核过程存疑数据一览表').bold = True
+    paragraph_12.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据审核过程存疑数据一览表.xlsx', level=4)
+    doc.add_heading('五、附表', level=1)
+    doc.add_heading('附表1:某区三普样品数量统计表(表层)', level=2)
+    # 插入附表1
+    table_1_f = doc.add_table(rows=lenNum_1 + 1, cols=3, style='Light Shading Accent 1')
+    table_1_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1_f.cell(2, 2).text = ''
+        table_1_f.cell(1, 2).merge(table_1_f.cell(2, 2))
+
+    doc.add_heading('附表2:各指标频度分析表', level=2)
+    # 插入表格 写入数据
+    table_f_2_data = table_f_2_data.replace(np.nan, '')
+    makeInfoTable(table_f_2_data, doc)
+    # table_f_2 = doc.add_table(rows=len(table_f_2_data) + 1, cols=6, style='Light Shading Accent 1')
+    # for i, row in enumerate(table_f_2.rows):
+    #     for j, cell in enumerate(row.cells):
+    #         # 获取单元格中的段落对象
+    #         paragraph = cell.paragraphs[0]
+    #         if i == 0:
+    #             r = paragraph.add_run(str(table_f_2_data.columns[j]))
+    #             r.font.bold = True
+    #         else:
+    #             r = paragraph.add_run(str(table_f_2_data.iloc[i - 1, j]))
+    #         r.font.size = Pt(10.5)
+    #         r.font.name = 'Times New Roman'
+    #         r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    #         paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+    #         paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+    #         paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:频度分析表.xlsx', level=4)
+    doc.add_heading('附表3:各指标频度分析图', level=2)
+    # 插入频度信息的图形
+
+    if os.path.isfile(f'{mkdir_path}/pH分析图.png'):
+        doc.add_picture(f'{mkdir_path}/pH分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总镉分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总镉分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总铬分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总铬分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总汞分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总汞分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总镍分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总镍分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总砷分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总砷分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总铅分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总铅分析图.png', width=Inches(6.0))
+    doc.add_heading('附表4:数值修约标准', level=2)
+    # 读取数据 插入表格 写入数据
+    numData = pd.read_excel('./img/数值修约要求.xlsx', sheet_name='Sheet1')
+    table_2_f = doc.add_table(rows=len(numData) + 1, cols=2, style='Light Shading Accent 1')
+    table_2_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(numData.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(numData.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # 处理样式 遍历所有的段落 修改字体
+    # 遍历并打印每个段落的文本
+    paragraphs = doc.paragraphs
+    for paragraph in paragraphs:
+        for run in paragraph.runs:
+            run.font.color.rgb = RGBColor(0, 0, 0)
+            run.font.name = 'Times New Roman'
+            run.font.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+            # run.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    # 保存Word文档
+
+    doc.save(f'{mkdir_path}/{areaName}-{type}审核报告.docx')
+
+
+
+
+

+ 979 - 0
public.py

@@ -0,0 +1,979 @@
+import pandas as pd
+import numpy as np
+# 这里写所有表格的判断规则 按顺序每个表格一个函数 方便后续修改
+pd.set_option('display.max_columns', 1000)
+pd.set_option('display.width', 1000)
+pd.set_option('display.max_colwidth', 1000)
+# 表1 土壤容重机械组成数据 为了方便做具体修改
+def soil_bulk_density(arr): #arr为计算过的数组
+    # (1)土壤容重不在[0.8, 1.6]范围以内的,存疑
+    shenHeList=[] # 定义一个数组存放容重存疑的数据
+    shenHeTarget = [] # 存放每条数据 有问题的指标
+    try:
+        for i in arr['土壤容重平均值(g/cm3)(计算)']:
+            if i > 1.6 or i < 0.8:
+                shenHeList.append('土壤容重:超阈值。')
+                shenHeTarget.append('土壤容重平均值。')
+            else:
+                shenHeList.append('')
+                shenHeTarget.append('')
+    except Exception as err:
+        print('土壤容重判断出错!请检查soil_bulk_density中判断土壤容重内容',err)
+    # (2)土壤利用类型→耕地、园地→相对极差>15 %,存疑;土壤利用类型→林地、草地→相对极差>20 %,存疑
+    tRTypeList = [] # 定义一个数组存放土壤利用类型存疑的数据
+    tRTypeTarget= [] # 定义一个数组存放土壤利用类型存疑的数据指标名称
+    try:
+        for i in arr['相对极差(%)']:
+            if i > 15 and arr.loc[arr['相对极差(%)'] == i, '土地利用类型'].iloc[0] == '耕地园地':
+                tRTypeList.append('存疑:耕地园地相对极差>15%。')
+                tRTypeTarget.append('耕地园地极差。')
+            elif i > 20 and arr.loc[arr['相对极差(%)'] == i, '土地利用类型'].iloc[0] == '林地草地':
+                tRTypeList.append('存疑:林地草地相对极差>20%。')
+                tRTypeTarget.append('林地草地极差。')
+            else:
+                tRTypeList.append('')
+                tRTypeTarget.append('')
+    except Exception as err:
+        print('相对极差判断、土壤利用类型判断出错!请检查soil_bulk_density中判断相对极差判断、土壤利用类型内容',err)
+    # (3)加和不在[99.98, 100.02]范围内的,存疑
+    plusShenHeList = [] # 定义一个数组存放加和存疑的数据
+    plusShenHeTarget = [] # 保存土壤颗粒加和存疑的指标
+    try:
+        for i in arr['加和%']:
+            if float(i) > 100.02 or float(i) < 99.98:
+                plusShenHeList.append('土壤颗粒加和:超阈值。')
+                plusShenHeTarget.append('土壤颗粒含量加和。')
+            else:
+                plusShenHeList.append('')
+                plusShenHeTarget.append('')
+    except Exception as err:
+        print('颗粒含量加和判断出错!请检查soil_bulk_density中判断颗粒含量加和内容',err)
+    # 根据国际土壤质地类型三角形编程实现对质地的分类→判断质地分类和质地名称是否正确
+    # 判断土壤类型逻辑:
+    soilList = []  # 定义一个数组存放土地类型的数据
+    soilContent = []
+    soilContentTarget = [] # 存放土壤质地异常的指标名称
+    xSLErr = []  # 存放ph>7 洗失量为空的异常数据
+    xSLTarget = []  # 存放异常数据 指标名称
+    try:
+        # 按行循环读取所有数据
+        for index, row in arr.iterrows():
+            # 1.将0.02-0.2,0.2-2两列加起来
+            plusSoil = row['0.2-0.02mm颗粒含量%'] + row['2-0.2mm颗粒含量%']
+            small_002_list = row['0.02-0.002mm颗粒含量%']
+            small_0002_list = row['0.002mm以下颗粒含量%']
+            if np.isnan(plusSoil) or np.isnan(small_002_list) or np.isnan(small_0002_list):
+                soilList.append('')
+            # 具体判断 这里为了方便看 减少了嵌套逻辑
+            elif small_0002_list >=65 and  small_0002_list <100: # 2. <0.002含量 65-100 ->重黏土
+                soilList.append('重黏土')
+            elif small_0002_list >= 45 and small_0002_list <65: # 3.<0.002含量 45-65 ->黏土
+                soilList.append('黏土')
+            elif small_0002_list >= 25 and small_0002_list <45 and small_002_list >= 45 and small_002_list <75: # 4. <0.002含量 25-45 and 0.002-0.02含量 45-75 -> 粉(砂)质黏土
+                soilList.append('粉(砂)质黏土')
+            elif small_0002_list >= 25 and small_0002_list<45 and  small_002_list>=0 and small_002_list<45 and plusSoil>=10 and plusSoil <55: # 5. <0.002含量 25-45 and 0.002-0.02含量 0-45 and 0.02-2含量 10-55-> 壤质黏土
+                soilList.append('壤质黏土')
+            elif small_0002_list >= 25 and small_0002_list<45 and  small_002_list>=0 and small_002_list<20 and plusSoil>=55 and plusSoil <75:# 6. <0.002含量 25-45 and 0.002-0.02含量 0-20 and 0.02-2含量 55-75-> 砂质黏土
+                soilList.append('砂质黏土')
+            elif small_0002_list >= 15 and small_0002_list<25 and  small_002_list>=45 and small_002_list<85: # 7.<0.002含量 15-25 and 0.002-0.02含量 45-85 -> 粉(砂)质黏壤土
+                soilList.append('粉(砂)质黏壤土')
+            elif small_0002_list >= 15 and small_0002_list<25 and  small_002_list>=20 and small_002_list<45 and plusSoil>=30 and plusSoil <55:# 8.<0.002含量 15-25 and 0.002-0.02含量 20-45 and 0.02-2含量 30-55-> 黏壤土
+                soilList.append('黏壤土')
+            elif small_0002_list >= 15 and small_0002_list<25 and  small_002_list>=0 and small_002_list<30 and plusSoil>=55 and plusSoil <85:# 9.<0.002含量 15-25 and 0.002-0.02含量 0-30 and 0.02-2含量 55-85-> 砂质黏壤土
+                soilList.append('砂质黏壤土')
+            elif small_0002_list >= 0 and small_0002_list<15 and  small_002_list>=45 and small_002_list<100:#10.<0.002含量 0-15 and 0.002-0.02含量 45-100 ->粉(砂)质壤土
+                soilList.append('粉(砂)质壤土')
+            elif  small_0002_list >= 0 and small_0002_list<15 and  small_002_list>=30 and small_002_list<45 and plusSoil>=40 and plusSoil <55: # 11.<0.002含量 0-15 and 0.002-0.02含量 30-45 and 0.02-2含量 40-55-> 壤土
+                soilList.append('壤土')
+            elif small_0002_list >= 0 and small_0002_list<15 and  small_002_list>=0 and small_002_list<45 and plusSoil>=55 and plusSoil <85: # 12.<0.002含量 0-15 and 0.002-0.02含量 0-45 and 0.02-2含量 55-85-> 砂质壤土
+                soilList.append('砂质壤土')
+            elif small_0002_list >= 0 and small_0002_list<15 and  small_002_list>=0 and small_002_list<15 and plusSoil>=85 and plusSoil <100: # 13.<0.002含量 0-15 and 0.002-0.02含量 0-15 and 0.02-2含量 85-100-> 砂土及壤质砂土
+                soilList.append('砂土及壤质砂土')
+            else:
+                soilList.append('') # 除所有情况外 还有空值
+
+        # 比较和原有数据是否一致
+        arr['土壤类型(判断)'] = soilList
+        for index, row in arr.iterrows():
+            if (row['土壤类型(判断)'] != row['土壤质地']) and (not pd.isna(row['土壤质地'])):
+                soilContent.append('存疑:土壤质地不一致')
+                soilContentTarget.append('土壤质地。')
+            else:
+                soilContent.append('')
+                soilContentTarget.append('')
+            # 如果pH>7,则洗失量数据不能为空;
+            if (not pd.isna(row['pH']) and row['pH'] > 7 and pd.isna(row['洗失量(吸管法需填)%'])):
+                xSLErr.append('洗失量:ph>7但洗失量未检测。')
+                xSLTarget.append('洗失量。')
+            else:
+                xSLErr.append('')
+                xSLTarget.append('')
+    except Exception as err:
+        print('土壤类型判断出错!请检查soil_bulk_density中判断土壤类型内容', err)
+    # 把存疑数据组合并返回
+    # print('shenHeList--',shenHeList,len(shenHeList))
+    # print('plusShenHeList--', plusShenHeList, len(plusShenHeList))
+    # print('tRTypeList--', tRTypeList, len(tRTypeList))
+    # print('soilContent--', soilContent, len(soilContent))
+    # print('soilList--', soilList, len(soilList))
+    pdData = pd.DataFrame({
+        '审核结果': pd.Series(shenHeList) + pd.Series(tRTypeList) + pd.Series(plusShenHeList) + pd.Series(soilContent) + pd.Series(xSLErr),
+        '土壤类型(判断)': soilList,
+        '异常指标': pd.Series(shenHeTarget) + pd.Series(tRTypeTarget) + pd.Series(plusShenHeTarget) + pd.Series(soilContentTarget) + pd.Series(xSLTarget),
+    })
+    return pdData
+# 这是一个判断范围的函数 如果需要修改范围 修改start end值就行
+
+def is_not_in_range(value):
+    return value <30 or value > 90
+
+
+# 表3 水稳性大团聚体规则判断函数
+def water_stable(arr):
+    # (1)不在[30, 90]范围以内的,存疑
+    shenHeList = []  # 定义一个数组存放团聚体存疑的数据
+    shenHeTar = [] # 存放水稳异常指标
+    # (2)总和超过90,存疑;耕地和园地>80,提示关注;林地和草地>90,提示关注
+    plusList = []
+    plusTar = [] # 水稳总和异常指标名称
+    soilType = []
+    # (3)>5mm指标占比超过10 %,存疑,应回溯
+    rateList = []
+    rateTar = [] # >5mm占比异常指标
+    try:
+        for index, row in arr.iterrows():
+            # 规则1判断 先判断值是否存在
+            if (not pd.isna(row['>5mm%']) and is_not_in_range(row['>5mm%'])) or (
+                    not pd.isna(row['3-5mm%']) and is_not_in_range(row['3-5mm%'])) or (
+                    not pd.isna(row['2-3mm%']) and is_not_in_range(row['2-3mm%'])) or (
+                    not pd.isna(row['1-2mm%']) and is_not_in_range(row['1-2mm%'])) or (
+                    not pd.isna(row['0.5-1mm%']) and is_not_in_range(row['0.5-1mm%'])) or (
+                    not pd.isna(row['0.25-0.5mm%']) and is_not_in_range(row['0.25-0.5mm%'])):
+                shenHeList.append('存疑:团聚体百分比不在范围以内。')
+                shenHeTar.append('水稳分项指标。')
+            else:
+                shenHeList.append('')
+                shenHeTar.append('')
+            # 规则2判断
+            if row['总和(%)'] > 90:
+                plusList.append('存疑:大团聚体总和超过90%。')
+                plusTar.append('水稳总和。')
+            else:
+                plusList.append('')
+                plusTar.append('')
+            if (row['土地利用类型'] == '耕地园地' and row['总和(%)'] > 80) or (row['土地利用类型'] == '林地草地' and row['总和(%)'] > 90):
+                soilType.append('关注:耕地园地团聚体总和大于80或林地草地团聚体总和大于90。')
+            else:
+                soilType.append('')
+            if row['>5mm%'] > 10:
+                rateList.append('存疑:>5mm占比超过10%应回溯。')
+                rateTar.append('水稳>5mm。')
+            else:
+                rateList.append('')
+                rateTar.append('')
+        resData = pd.DataFrame({
+                '审核结果': pd.Series(shenHeList) + pd.Series(plusList) + pd.Series(soilType) + pd.Series(rateList),
+                '异常指标': pd.Series(shenHeTar) + pd.Series(plusTar) + pd.Series(rateTar),
+                })
+        return resData
+    except Exception as err:
+        print('大团聚体判断出错!请检查water_stable中判断大团聚体内容', err)
+
+# 表5  pH、阳离子交换量、交换性盐基基础数据判断
+# 判断土壤类型和阳离子交换量 盐基饱和度的范围
+def soilTypeValue(row): # 传入一行数据
+    strValue = row['土壤类型']
+    soilType = ''
+
+    if isinstance(strValue, str):
+        # print('type---', strValue.split('_'))
+        # print('strValue',strValue)
+        if len(strValue.split('_')) > 1:
+            soilType = strValue.split('_')[1] # 获取到土壤类型
+
+    cationChange = row['阳离子交换量Cmol(+)/kg'] # 获取到阳离子交换量
+    bHValue = (row['交换性盐总量Cmol(+)/kg']/row['阳离子交换量Cmol(+)/kg'] )*100# 计算出的盐基饱和度
+    # 判断三者范围是否合理
+    res = ''
+    if soilType == '黄红壤':
+        if pd.isna(cationChange) and (cationChange > 10 and cationChange<24) and  pd.isna(bHValue) and (bHValue > 30 and bHValue<50):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '棕红壤':
+        if pd.isna(cationChange) and (cationChange > 6 and cationChange < 15) and pd.isna(bHValue) and (
+                bHValue > 25 and bHValue < 70):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '红壤性土':
+        if pd.isna(cationChange) and (cationChange > 5 and cationChange < 15) and pd.isna(bHValue) and (
+                bHValue > 10 and bHValue < 50):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '典型黄壤':
+        if pd.isna(cationChange) and (cationChange > 5 and cationChange < 15) and pd.isna(bHValue) and (
+                 bHValue < 30):
+            res = ''
+        else:
+            res = '该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '黄壤性土':
+        if pd.isna(cationChange) and (cationChange > 10 and cationChange < 18) and pd.isna(bHValue) and (
+                 bHValue < 45):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '典型黄棕壤' or soilType == '暗黄棕壤' or soilType == '黄棕壤性土':
+        if pd.isna(cationChange) and (cationChange > 8 and cationChange < 22) and pd.isna(bHValue) and (
+                bHValue > 30 and bHValue < 60):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '典型黄褐土' or soilType == '黏盘黄褐土' or soilType == '粘盘黄褐土' or soilType == '粘盘黄褐土' or soilType=='白浆化黄褐土' or soilType=='黄褐土性土':
+        if pd.isna(cationChange) and (cationChange > 15 and cationChange < 25) and pd.isna(bHValue) and (
+                bHValue > 60 and bHValue < 85):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '粘盘黄褐土':
+        if pd.isna(cationChange) and (cationChange > 10 and cationChange < 30) and pd.isna(bHValue) and (
+                bHValue > 75 and bHValue < 95):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '典型棕壤' or soilType == '白浆化棕壤' or soilType == '潮棕壤' or soilType == '棕壤性土' or soilType == '棕壤性土':
+        if pd.isna(cationChange) and (cationChange > 5 and cationChange < 20) and pd.isna(bHValue) and (
+                cationChange > 25 and cationChange < 65):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '典型山地草甸土' or soilType == '山地草原草甸土' or soilType == '山地灌丛草甸土':
+        if pd.isna(cationChange) and (cationChange > 10 and cationChange < 20) and pd.isna(bHValue) and (
+                bHValue > 15 and bHValue < 30):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '酸性紫色土' or soilType == '中性紫色土' or soilType == '石灰性紫色土':
+        if pd.isna(cationChange) and (cationChange > 10 and cationChange < 20) and pd.isna(bHValue) and (
+                bHValue > 50 and bHValue < 70):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '红色石灰土' or soilType == '黑色石灰土' or soilType == '棕色石灰土' or soilType == '黄色石灰土' :
+        if pd.isna(cationChange) and (cationChange > 15 and cationChange < 30) and pd.isna(bHValue) and (
+                bHValue > 70 and bHValue < 100):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '酸性石质土' or soilType == '中性石质土' or soilType == '钙质石质土' or soilType == '含盐石质土':
+        if pd.isna(cationChange) and (cationChange > 10 and cationChange < 15) and pd.isna(bHValue) and (
+                bHValue > 45 and bHValue < 65):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '酸性粗骨土' or soilType == '中性粗骨土' or soilType == '钙质粗骨土' or soilType == '硅质盐粗骨土':
+        if pd.isna(cationChange) and (cationChange > 5 and cationChange < 15) and pd.isna(bHValue) and (
+                bHValue > 20 and bHValue < 50):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '典型潮土' or soilType == '灰潮土' or soilType == '脱潮土' or soilType == '湿潮土' or soilType == '盐化潮土' or soilType == '碱化潮土' or soilType == '灌於潮土':
+        if pd.isna(cationChange) and (cationChange > 10 and cationChange < 30) and pd.isna(bHValue) and (
+                bHValue > 70 and bHValue < 100):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '典型砂姜黑土' or soilType == '石灰性砂姜黑土' or soilType == '盐化砂姜黑土' or soilType == '碱化砂姜黑土' or soilType == '黑粘土':
+        if pd.isna(cationChange) and (cationChange > 18 and cationChange < 35) and pd.isna(bHValue) and (
+                bHValue > 90 and bHValue < 100):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '淹育水稻土':
+        if pd.isna(cationChange) and (cationChange > 20 and cationChange < 30) and pd.isna(bHValue) and (
+                bHValue > 85 and bHValue < 90):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '潴育水稻土':
+        if pd.isna(cationChange) and (cationChange > 12 and cationChange < 20) and pd.isna(bHValue) and (
+                bHValue > 60 and bHValue < 80):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '潜育水稻土':
+        if pd.isna(cationChange) and (cationChange > 15 and cationChange < 25) and pd.isna(bHValue) and (
+                bHValue > 75 and bHValue < 90):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    elif soilType == '漂洗水稻土':
+        if pd.isna(cationChange) and (cationChange > 10 and cationChange < 20) and pd.isna(bHValue) and (
+                bHValue > 65 and bHValue < 80):
+            res = ''
+        else:
+            res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
+    return res
+def cation_value(arr):
+    phList = [] # 保存ph存疑数据
+    cationList = [] # 保存阳离子存疑数据
+    exchangeableSalt = [] # 保存交换性盐基总量存疑数据
+    exchangeableCa = [] # 保存交换性钙总量存疑数据
+    exchangeableMg = []  # 保存交换性镁总量存疑数据
+    exchangeableK = []  # 保存交换性钾总量存疑数据
+    exchangeableNa = []  # 保存交换性钠总量存疑数据
+    summaryList = [] # 保存ph 离子和 盐基饱和度范围存疑数据
+    soilTypeList = [] # 保存土壤类型 阳离子交换量cmol(+)/kg 和盐基饱和度范围存疑数据
+    waterMount = [] # 保存含水量存疑数据 含水量应小于10%
+
+    phTar = [] # 保存ph异常指标
+    cationTar = [] # 保存阳离子异常指标
+    exchangeableSaltTar = []  # 保存交换性盐基总量异常指标
+    exchangeableCaTar = []  # 保存交换性钙异常指标
+    exchangeableMgTar = []  # 保存交换性镁异常指标
+    exchangeableKTar = []  # 保存交换性钾异常指标
+    exchangeableNaTar = []  # 保存交换性钠异常指标
+    summaryListTar = []  # 保存ph 离子和 盐基饱和度异常指标
+    soilTypeListTar = []  # 保存土壤类型 阳离子交换量cmol(+)/kg 和盐基饱和度异常数据
+    waterMountTar = []  # 保存含水量异常指标
+
+    try:
+        for index, row in arr.iterrows():
+            # 风干样含水量 0.5-5,存疑
+            if pd.isna(row['含水量']) or row['含水量'] > 5 or row['含水量'] < 0.5:
+                waterMount.append('风干试样含水量(分析基):超阈值。')
+                waterMountTar.append('风干试样含水量(分析基)。')
+            else:
+                waterMount.append('')
+                waterMountTar.append('')
+            # (1)pH在[4, 9]范围之外的,存疑;
+            if pd.isna(row['pH']) or row['pH'] < 4 or row['pH'] > 9:
+                phList.append('pH:超阈值。')
+                phTar.append('pH。')
+            else:
+                phList.append('')
+                phTar.append('')
+            # (2)阳离子交换量在[6, 38]范围之外的,存疑;
+            if row['阳离子交换量Cmol(+)/kg'] < 6 or row['阳离子交换量Cmol(+)/kg'] > 38:
+                cationList.append('阳离子交换量:超阈值。')
+                cationTar.append('阳离子交换量。')
+            else:
+                cationList.append('')
+                cationTar.append('')
+            # (3)交换性盐基总量在[3, 30]范围之外的,存疑;
+            if row['交换性盐总量Cmol(+)/kg'] <3 or row['交换性盐总量Cmol(+)/kg'] > 30:
+                exchangeableSalt.append('交换性盐基总量:超阈值。')
+                exchangeableSaltTar.append('交换性盐总量。')
+            else:
+                exchangeableSalt.append('')
+                exchangeableSaltTar.append('')
+            # (4)交换性钙在[1, 25]范围之外的,存疑;
+            if row['交换性钙Cmol(1/2Ca2+)/kg'] < 1 or row['交换性钙Cmol(1/2Ca2+)/kg'] > 25:
+                exchangeableCa.append('交换性钙:交换性钙超阈值。')
+                exchangeableCaTar.append('交换性钙。')
+            else:
+                exchangeableCa.append('')
+                exchangeableCaTar.append('')
+            # (5)交换性镁在[0.5, 12.5]范围之外的,存疑;
+            if row['交换性镁cmol(1/2Mg2+)/kg'] < 0.5 or row['交换性镁cmol(1/2Mg2+)/kg'] > 12.8:
+                exchangeableMg.append('交换性镁:超阈值。')
+                exchangeableMgTar.append('交换性镁。')
+            else:
+                exchangeableMg.append('')
+                exchangeableMgTar.append('')
+            # (6)交换性钾在[0.1, 1.5]范围之外的,存疑;
+            if row['交换性钾Cmol(+)/kg'] < 0.1 or row['交换性钾Cmol(+)/kg'] > 1.5:
+                exchangeableK.append('交换性钾:超阈值。')
+                exchangeableKTar.append('交换性钾。')
+            else:
+                exchangeableK.append('')
+                exchangeableKTar.append('')
+            # (7)交换性钠在[0.3, 1.9]范围之外的,存疑;
+            if row['交换性钠cmol(+)/kg'] < 0.3 or row['交换性钠cmol(+)/kg'] > 1.9:
+                exchangeableNa.append('交换性钠:超阈值。')
+                exchangeableNaTar.append('交换性钠。')
+            else:
+                exchangeableNa.append('')
+                exchangeableNaTar.append('')
+            # (8)pH<7.5,阳离子交换量>交换性盐总量>四大离子之和,且盐基饱和度小于100 %;违反则存疑;pH≥7.5,交换性盐总量 = 四大离子之和,盐基饱和度范围在80~120 %;违反则存疑;
+            if ((not pd.isna(row['pH']) and row['pH']<7.5 and row['阳离子交换量Cmol(+)/kg']>row['交换性盐总量Cmol(+)/kg']>row['四大离子之和'] and row['盐基饱和度%']*100 <80 ) or
+                    ((not pd.isna(row['pH']) and row['pH']>=7.5 and row['交换性盐总量Cmol(+)/kg']==row['四大离子之和'] and (row['盐基饱和度%'] <120 and row['盐基饱和度%'] >80 ))) or
+                    ((not pd.isna(row['pH']) and row['pH']<6 and row['盐基饱和度%'] >80))
+            ):
+                summaryList.append('')
+                summaryListTar.append('')
+            else:
+                summaryList.append('存疑:ph值、阳离子交换量、交换性盐总量、离子总和、盐基饱和度之间关系存疑。')
+                summaryListTar.append('盐基饱和度。')
+            soilRes = soilTypeValue(row)
+            soilTypeList.append(soilRes)
+        # print('pd.Series(phList)',pd.Series(phList) + pd.Series(cationList)+pd.Series(exchangeableSalt))
+        # print('pd.Series(cationList)', pd.Series(exchangeableSalt))
+        # print('res---',  pd.Series(phList)+pd.Series(cationList)+pd.Series(exchangeableSalt)+pd.Series(exchangeableCa)+pd.Series(exchangeableMg)+pd.Series(exchangeableK)+pd.Series(exchangeableNa)+pd.Series(summaryList))
+        checkData = pd.DataFrame({
+            '审核结果': pd.Series(phList)+pd.Series(cationList)+pd.Series(exchangeableSalt)+pd.Series(exchangeableCa)+pd.Series(exchangeableMg)+pd.Series(exchangeableK)+pd.Series(exchangeableNa)+pd.Series(summaryList)+pd.Series(soilTypeList)+pd.Series(waterMount),
+            '异常指标': pd.Series(phTar)+pd.Series(cationTar)+pd.Series(exchangeableSaltTar)+pd.Series(exchangeableCaTar)+pd.Series(exchangeableMgTar)+pd.Series(exchangeableKTar)+pd.Series(exchangeableNaTar)+pd.Series(summaryListTar)+pd.Series(waterMountTar)
+        })
+        return checkData
+    except Exception as err:
+        print('阳离子量判断出错!请检查cation_value中判断阳离子量内容', err)
+
+# 表8  8大离子基础数据判断
+def eight_ion_coun(arr, summary):
+    try:
+        allArr = [] # 存储水溶性盐总量存疑数据
+        conductivity = [] # 存储电导率存疑数据
+        naArr = [] # 存储钠离子存疑数据
+        kArr = []  # 存储钾离子存疑数据
+        caArr = []  # 存储钙离子存疑数据
+        mgArr = []  # 存储镁离子存疑数据
+        coArr = []  # 存储碳酸根离子存疑数据
+        cohArr = []  # 存储碳酸氢根离子存疑数据
+        soArr = [] # 存储硫酸根离子存疑数据
+        clArr = [] # 氯离子存疑数据
+        totalCom = [] # 全盐量小于八大离子和存疑数据
+        phCoArr = [] # ph 碳酸根存疑数据
+        changeComArr = [] #交换性离子高于水溶性离子存疑数据
+        rateArr = [] # (水溶性全盐量-八大离子加和)/八大离子加和×100 存疑数据
+        subtractionArr=[] #阳离子-阴离子 不在范围内
+        # 存放异常指标
+        allArrTar = []  # 存储水溶性盐总量异常指标
+        conductivityTar = []  # 存储电导率异常指标
+        naArrTar = []  # 存储钠离子异常指标
+        kArrTar = []  # 存储钾离子异常指标
+        caArrTar = []  # 存储钙离子异常指标
+        mgArrTar = []  # 存储镁离子异常指标
+        coArrTar = []  # 存储碳酸根离子异常指标
+        cohArrTar = []  # 存储碳酸氢根离子异常指标
+        soArrTar = []  # 存储硫酸根离子异常指标
+        clArrTar = []  # 氯离子异常指标
+        totalComTar = []  # 全盐量小于八大离子和异常指标
+        phCoArrTar = []  # ph 碳酸根异常指标
+        changeComArrTar = []  # 交换性离子高于水溶性离子异常指标
+        rateArrTar = []  # (水溶性全盐量-八大离子加和)/八大离子加和×100 异常指标
+        subtractionArrTar = []  # 阳离子-阴离子 异常指标
+        #(2)水溶性盐总量在[0.1, 2]范围之外的,存疑;
+        for index, row in arr.iterrows():
+            if (not pd.isna(row['水溶性全盐量g/kg']) and row['水溶性全盐量g/kg'] < 0.1) or (not pd.isna(row['水溶性全盐量g/kg']) and row['水溶性全盐量g/kg'] > 2):
+                allArr.append('全盐量:超阈值。')
+                allArrTar.append('全盐量。')
+            else:
+                allArr.append('')
+                allArrTar.append('')
+            #(3)电导率在[0.01, 2]范围之外的,存疑;
+            if ( not pd.isna(row['电导率ms/cm']) and row['电导率ms/cm'] < 0.01) or (not pd.isna(row['电导率ms/cm']) and row['电导率ms/cm'] > 2):
+                conductivity.append('电导率:超阈值。')
+                conductivityTar.append('电导率。')
+            else:
+                conductivity.append('')
+                conductivityTar.append('电导率')
+            #(4)水溶性钠在[0.05, 0.5]范围之外的,存疑;
+            if (not pd.isna(row['水溶性钠离子含量Cmol(Na+)/kg']) and row['水溶性钠离子含量Cmol(Na+)/kg'] <0.05) or (pd.isna(row['水溶性钠离子含量Cmol(Na+)/kg']) and row['水溶性钠离子含量Cmol(Na+)/kg'] > 0.5):
+                naArr.append('水溶性钠离子:水溶性钠离子超阈值。')
+                naArrTar.append('水溶性钠离子。')
+            else:
+                naArr.append('')
+                naArrTar.append('')
+            #(5)水溶性钾在[0.01, 0.5]范围之外的,存疑;
+            if (not pd.isna(row['水溶性钾离子含量Cmol(K+)/kg']) and row['水溶性钾离子含量Cmol(K+)/kg'] <0.01) or ( not pd.isna(row['水溶性钾离子含量Cmol(K+)/kg']) and row['水溶性钾离子含量Cmol(K+)/kg'] > 0.5):
+                kArr.append('水溶性钾离子:超阈值。')
+                kArrTar.append('水溶性钾离子。')
+            else:
+                kArr.append('')
+                kArrTar.append('')
+            #(6)水溶性钙在[0.25, 5]范围之外的,存疑;
+            if (not pd.isna(row['水溶性钙离子含量cmol(1/2Ca2+)/kg']) and row['水溶性钙离子含量cmol(1/2Ca2+)/kg'] <0.25) or (not pd.isna(row['水溶性钙离子含量cmol(1/2Ca2+)/kg']) and row['水溶性钙离子含量cmol(1/2Ca2+)/kg'] > 0.5):
+                caArr.append('水溶性钙离子:超阈值。')
+                caArrTar.append('水溶性钙离子。')
+            else:
+                caArr.append('')
+                caArrTar.append('')
+            #(7)水溶性镁在[0.125, 2.5]范围之外的,存疑;
+            if (not pd.isna(row['水溶性镁离子Cmol(1/2Mg2+)/kg']) and row['水溶性镁离子Cmol(1/2Mg2+)/kg'] <0.125) or  (not pd.isna(row['水溶性镁离子Cmol(1/2Mg2+)/kg']) and row['水溶性镁离子Cmol(1/2Mg2+)/kg'] > 2.5):
+                mgArr.append('水溶性镁离子:超阈值。')
+                mgArrTar.append('水溶性镁离子。')
+            else:
+                mgArr.append('')
+                mgArrTar.append('')
+            #(8)水溶性碳酸根在[0.01, 2.5]范围之外的,存疑;
+            if (not pd.isna(row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg']) and row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg'] <0.01) or (not pd.isna(row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg']) and row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg'] > 2.5):
+                coArr.append('水溶性碳酸根:超阈值。')
+                coArrTar.append('水溶性碳酸根。')
+            else:
+                coArr.append('')
+                coArrTar.append('')
+            #(9)水溶性碳酸氢根在[0.05, 5]范围之外的,存疑;
+            if (not pd.isna(row['水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg']) and row['水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg'] <0.05) or (not pd.isna(row['水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg']) and row['水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg'] > 5):
+                cohArr.append('水溶性碳酸氢根:超阈值。')
+                cohArrTar.append('水溶性碳酸氢根。')
+            else:
+                cohArr.append('')
+                cohArrTar.append('')
+            #(10)水溶性硫酸根在[0.25, 2.5]范围之外的,存疑;
+            if (not pd.isna(row['水溶性硫酸根离子含量cmol(1/2SO42-)/kg']) and row['水溶性硫酸根离子含量cmol(1/2SO42-)/kg'] <0.25) or (not pd.isna(row['水溶性硫酸根离子含量cmol(1/2SO42-)/kg']) and row['水溶性硫酸根离子含量cmol(1/2SO42-)/kg'] > 2.5):
+                soArr.append('水溶性硫酸根:超阈值。')
+                soArrTar.append('水溶性硫酸根。')
+            else:
+                soArr.append('')
+                soArrTar.append('')
+            #(11)水溶性氯根在[0.5, 5]范围之外的,存疑;
+            if (not pd.isna(row['水溶性氯离子含量cmol(Cl-)/kg']) and row['水溶性氯离子含量cmol(Cl-)/kg'] <0.5) or  (not pd.isna(row['水溶性氯离子含量cmol(Cl-)/kg']) and row['水溶性氯离子含量cmol(Cl-)/kg'] > 5):
+                clArr.append('水溶性氯根:超阈值。')
+                clArrTar.append('水溶性氯根。')
+            else:
+                clArr.append('')
+                clArrTar.append('')
+            #(12)水溶性盐总量大于等于八大离子之和,违背则存疑;土地利用类型为菜地的,可能不符合这个规律;
+            if (not pd.isna( row['水溶性全盐量g/kg']) and not pd.isna(row['八大离子加和g/kg']) and row['水溶性全盐量g/kg'] < row['八大离子加和g/kg']):
+                totalCom.append('存疑:水溶性全盐量小于八大离子之和。')
+                totalComTar.append('水溶性全盐量。')
+            else:
+                totalCom.append('')
+                totalComTar.append('')
+
+            #(13)水溶性八大离子换算为g / kg,如水溶性钠离子g / kg = 水溶性钠离子cmol(Na +) / kg×23g / mol×10 - 2; 这里在计算离子和时已转换
+            #(14)pH<8,碳酸根基本为0
+            if row['pH'] <8 and not pd.isna(row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg']) and row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg'] == 0:
+                phCoArr.append('水溶性碳酸根:pH<8且水溶性碳酸根为0。')
+                phCoArrTar.append('水溶性碳酸根。')
+            else:
+                phCoArr.append('')
+                phCoArrTar.append('')
+            #(15)交换性四大盐离子均要高于水溶性四大盐离子(钙镁钾钠)
+            naBool = not pd.isna(row['水溶性钠离子含量Cmol(Na+)/kg'])
+            kBool = not pd.isna(row['水溶性钾离子含量Cmol(K+)/kg'])
+            caBool = not pd.isna(row['水溶性钙离子含量cmol(1/2Ca2+)/kg'])
+            mgBool = not pd.isna(row['水溶性镁离子Cmol(1/2Mg2+)/kg'])
+            sumNa = not pd.isna(summary.loc[index,'交换性钠'])
+            sumK = not pd.isna(summary.loc[index, '交换性钾'])
+            sumCa = not pd.isna(summary.loc[index, '交换性钙'])
+            sumMg = not pd.isna(summary.loc[index, '交换性镁'])
+            if (naBool and sumNa and row['水溶性钠离子含量Cmol(Na+)/kg']>summary.loc[index,'交换性钠']) or (
+                    kBool and sumK and row['水溶性钾离子含量Cmol(K+)/kg']>summary.loc[index,'交换性钾']) or (
+                    caBool and sumCa and row['水溶性钙离子含量cmol(1/2Ca2+)/kg']>summary.loc[index,'交换性钙']) or (
+                   mgBool and sumMg and row['水溶性镁离子Cmol(1/2Mg2+)/kg']>summary.loc[index,'交换性镁']):
+                changeComArr.append('存疑:交换性盐基总量低于于水溶性盐离子。')
+            else:
+                changeComArr.append('')
+            #(16)(水溶性全盐量 - 八大离子加和) / 八大离子加和 * 100,不超过±20 %
+            if not pd.isna(row['(水溶性全盐量-八大离子加和)/水溶性全盐量×100']) and (row['(水溶性全盐量-八大离子加和)/水溶性全盐量×100'] < -0.2 or row['(水溶性全盐量-八大离子加和)/水溶性全盐量×100'] > 0.2) :
+                rateArr.append('存疑:(水溶性全盐量-八大离子加和)/水溶性全盐量×100超阈值。')
+            else:
+                rateArr.append('')
+            #(17)阳离子总量 - 阴离子总量应基本相等,超过±1则提示异常
+            if not pd.isna(row['阳离子总量-阴离子总量']) and (row['阳离子总量-阴离子总量'] < -1 or row['阳离子总量-阴离子总量'] > 1) :
+                subtractionArr.append('存疑:阳离子总量 - 阴离子总量超阈值。')
+            else:
+                subtractionArr.append('')
+        resData = pd.DataFrame({
+            '审核结果': pd.Series(allArr) + pd.Series(conductivity) + pd.Series(naArr) +
+                pd.Series(kArr) + pd.Series(caArr) + pd.Series(mgArr) + pd.Series(coArr) + pd.Series(
+                    cohArr) + pd.Series(soArr) + pd.Series(clArr) + pd.Series(totalCom) + pd.Series(
+                    phCoArr) + pd.Series(changeComArr) + pd.Series(rateArr) + pd.Series(subtractionArr),
+            '异常指标': pd.Series(allArrTar) + pd.Series(conductivityTar) + pd.Series(naArrTar) +
+                pd.Series(kArrTar) + pd.Series(caArrTar) + pd.Series(mgArrTar) + pd.Series(coArrTar) + pd.Series(
+                    cohArrTar) + pd.Series(soArrTar) + pd.Series(clArrTar) + pd.Series(totalComTar) + pd.Series(
+                    phCoArrTar)
+        })
+        return resData
+    except Exception as err:
+        print('八大离子判断出错!请检查eight_ion_coun中判断离子内容', err)
+
+# 表10 有机质、全氮、全磷、全钾数据
+def nutrient_data(arr):
+    try:
+        organicMatter = [] # 有机质存疑数据
+        NArr = [] # 全氮存疑数据
+        PArr = [] # 全磷存疑数据
+        KArr = [] # 全钾存疑数据
+        availableP = [] # 有效磷存疑数据
+        availablek = [] #速效钾存疑数据
+        slowlyK= [] #缓效钾存疑数据
+        organicRate = [] #有机质 / 全氮比值存疑数据
+        availablePCom = [] #有效磷<3和大于60,提示异常;
+        availableTxt = [] # 速效钾<50提示异常
+        availablekCom = [] # 速效钾>缓效钾 存疑数据
+        sKErr = []  # 保存交换性钾不等于速效钾
+        # 异常指标
+        organicMatterTar = []  # 有机质异常指标
+        NArrTar = []  # 全氮异常指标
+        PArrTar = []  # 全磷异常指标
+        KArrTar = []  # 全钾异常指标
+        availablePTar = []  # 有效磷异常指标
+        availablekTar = []  # 速效钾异常指标
+        slowlyKTar = []  # 缓效钾异常指标
+        sKErrTar = []  # 保存交换性钾不等于速效钾
+        for index, row in arr.iterrows():
+            # 交换性钾 == 速效钾
+            if not pd.isna(row['速效钾mg/kg']) and not pd.isna(row['交换性钾']) and ((row['速效钾mg/kg'] - row['交换性钾']*391) / (row['交换性钾']*391) > 0.2 or (row['速效钾mg/kg'] - row['交换性钾']*391)/ (row['交换性钾']*391) < -0.2):
+                sKErr.append('存疑:交换性钾和速效钾误差超20%。')
+                sKErrTar.append('交换性钾、速效钾。')
+            else:
+                sKErr.append('')
+                sKErrTar.append('')
+            #(2)有机质在[2, 50]范围之外的,存疑;有机质<5提示异常;
+            if row['有机质g/kg'] < 2 or row['有机质g/kg'] >50:
+                organicMatter.append('有机质:超阈值。')
+                organicMatterTar.append('有机质。')
+            else:
+                organicMatter.append('')
+                organicMatterTar.append('')
+            #(3)全氮在[0.1, 2.5]范围之外的;存疑;
+            if row['全氮g/kg'] < 0.1 or row['全氮g/kg'] > 2.5:
+                NArr.append('全氮:超阈值。')
+                NArrTar.append('全氮。')
+            else:
+                NArr.append('')
+                NArrTar.append('')
+            #(4)全磷在[0.18, 1.5]范围之外的;存疑;
+            if row['全磷g/kg'] < 0.18 or row['全磷g/kg'] > 1.5:
+                PArr.append('全磷:超阈值。')
+                PArrTar.append('全磷。')
+            else:
+                PArr.append('')
+                PArrTar.append('')
+            #(5)全钾在[10, 29]范围之外的;存疑;
+            if row['全钾g/kg'] < 10 or row['全钾g/kg'] > 29:
+                KArr.append('全钾:超阈值。')
+                KArrTar.append('全钾。')
+            else:
+                KArr.append('')
+                KArrTar.append('')
+            #(6)有效磷在[1, 80]范围之外的;存疑; 耕地 超过80存疑
+            if (row['pH'] >= 6.5 and (row['有效磷g/kg'] < 3 or row['有效磷g/kg'] > 60)) or (row['pH'] < 6.5 and (row['有效磷g/kg'] <1 or row['有效磷g/kg'] > 80) or (row['编号'][6:10] == '0101' or row['编号'][6:10] == '0102' or row['编号'][6:10] == '0103') and row['有效磷g/kg'] > 60) :
+                availableP.append('有效磷:超阈值。')
+                availablePTar.append('有效磷。')
+            else:
+                availableP.append('')
+                availablePTar.append('')
+            # if row['有效磷g/kg'] < 1 or row['有效磷g/kg'] > 60 or ((row['编号'][6:11] == '0101' or row['编号'][6:11] == '0102' or row['编号'][6:11] == '0103') and row['有效磷g/kg'] > 60):
+            #     availableP.append('存疑:有效磷超阈值。')
+            # else:
+            #     availableP.append('')
+            #(7)速效钾在[30, 300] 范围之外的;存疑; 耕地超过300存疑
+            if row['速效钾mg/kg'] < 30 or row['速效钾mg/kg'] > 300 or ((row['编号'][6:10] == '0101' or row['编号'][6:10] == '0102' or row['编号'][6:10] == '0103') and row['速效钾mg/kg'] > 300):
+                availablek.append('速效钾:超阈值。')
+                availablekTar.append('速效钾。')
+            else:
+                availablek.append('')
+                availablekTar.append('')
+            #(8)缓效钾在[100, 2000]范围之外的;存疑;
+            if row['缓效钾mg/kg'] < 100 or row['缓效钾mg/kg'] > 2000:
+                slowlyK.append('缓效钾:超阈值。')
+                slowlyKTar.append('缓效钾。')
+            else:
+                slowlyK.append('')
+                slowlyKTar.append('')
+            #(9)有机质 / 全氮比值≥20和≤13,提示存疑
+            if row['有机质g/kg']/row['全氮g/kg'] >=20 or row['有机质g/kg']/row['全氮g/kg'] <=13 :
+                organicRate.append('存疑:有机质/全氮比值超阈值。')
+            else:
+                organicRate.append('')
+            #(10)有机质、全氮含量异常高,但速效养分特低,提示异常   无法量化不处理
+            #(11)母岩为片麻岩,但全钾、速效缓效钾含量低,提示异常   无法量化不处理
+            #(12)有效磷<3和大于60,提示异常;速效钾<50提示异常
+            if row['有效磷g/kg'] < 3 or row['有效磷g/kg'] > 60:
+                availablePCom.append('有效磷:超阈值。')
+            else:
+                availablePCom.append('')
+            if row['速效钾mg/kg'] < 50:
+                availableTxt.append('速效钾:超阈值。')
+            else:
+                availableTxt.append('')
+            #(13)速效钾>缓效钾,提示异常
+            if row['速效钾mg/kg'] > row['缓效钾mg/kg']:
+                availablekCom.append('异常:速效钾大于缓效钾。')
+            else:
+                availablekCom.append('')
+        resData = pd.DataFrame({
+            '审核结果': pd.Series(organicMatter) + pd.Series(NArr) + pd.Series(PArr) +
+                pd.Series(KArr) + pd.Series(availableP) + pd.Series(availablek) + pd.Series(slowlyK) + pd.Series(
+                    organicRate) + pd.Series(availablePCom) + pd.Series(availablekCom) + pd.Series(availableTxt) + pd.Series(availablePCom) + pd.Series(sKErr),
+            '异常指标': pd.Series(organicMatterTar) + pd.Series(NArrTar) + pd.Series(PArrTar) +
+                pd.Series(KArrTar) + pd.Series(availablePTar) + pd.Series(availablekTar) + pd.Series(slowlyKTar) + pd.Series(sKErrTar)
+        })
+        return resData
+    except Exception as err:
+        print('有机质、全氮、全磷、全钾数据判断出错!请检查nutrient_data中判断内容', err)
+
+
+# 表12 土壤指标判断规则
+def soil_metal(arr):
+    try:
+        effectiveL = []  # 有效硫存疑数据
+        effectiveG = []  # 有效硅存疑数据
+        effectiveT = []  # 有效铁存疑数据
+        effectiveM = []  # 有效锰存疑数据
+        effectiveCu = []  # 有效铜存疑数据
+        effectiveX = []  # 有效锌存疑数据
+        effectiveP = []  # 有效硼存疑数据
+        effectiveMu = []  # 有效钼存疑数据
+        # 存疑指标
+        effectiveLTar = []  # 有效硫
+        effectiveGTar = []  # 有效硅
+        effectiveTTar = []  # 有效铁
+        effectiveMTar = []  # 有效锰
+        effectiveCuTar = []  # 有效铜
+        effectiveXTar = []  # 有效锌
+        effectivePTar = []  # 有效硼
+        effectiveMutar = []  # 有效钼
+        for index, row in arr.iterrows():
+            #(1)有效硫在[2, 60]范围之外的,存疑;
+            if (not pd.isna(row['有效硫mg/kg']) and row['有效硫mg/kg'] <2) or (not pd.isna(row['有效硫mg/kg']) and row['有效硫mg/kg'] >60):
+                effectiveL.append('有效硫:超阈值。')
+                effectiveLTar.append('有效硫。')
+            else:
+                effectiveL.append('')
+                effectiveLTar.append('')
+            #(2)有效硅在[10, 500]范围之外的,存疑;
+            if ( not pd.isna(row['有效硅mg/kg']) and row['有效硅mg/kg'] <10) or (not pd.isna(row['有效硅mg/kg']) and row['有效硅mg/kg'] >500):
+                effectiveG.append('有效硅:超阈值。')
+                effectiveGTar.append('有效硅。')
+            else:
+                effectiveG.append('')
+                effectiveGTar.append('')
+            #(3)有效铁在[5, 300]范围之外的,存疑;
+            if ( not pd.isna(row['有效铁mg/kg']) and row['有效铁mg/kg'] <5) or (not pd.isna(row['有效铁mg/kg']) and row['有效铁mg/kg'] >300):
+                effectiveT.append('有效铁:超阈值。')
+                effectiveTTar.append('有效铁。')
+            else:
+                effectiveT.append('')
+                effectiveTTar.append('')
+            #(4)有效锰在[5, 200]范围之外的,存疑;
+            if (not pd.isna(row['有效锰mg/kg']) and row['有效锰mg/kg'] <5) or (not pd.isna(row['有效锰mg/kg']) and row['有效锰mg/kg'] >200) :
+                effectiveM.append('有效锰:超阈值。')
+                effectiveMTar.append('有效锰。')
+            else:
+                effectiveM.append('')
+                effectiveMTar.append('')
+            #(5)有效铜在[0.1, 8]范围之外的,存疑;
+            if ( not pd.isna(row['有效铜mg/kg']) and row['有效铜mg/kg'] <0.1) or (not pd.isna(row['有效铜mg/kg']) and row['有效铜mg/kg'] >8):
+                effectiveCu.append('有效铜:超阈值。')
+                effectiveCuTar.append('有效铜。')
+            else:
+                effectiveCu.append('')
+                effectiveCuTar.append('')
+
+            #(6)有效锌在[0.1, 10] 范围之外的,存疑;
+            if (not pd.isna(row['有效锌mg/kg']) and row['有效锌mg/kg'] <0.1) or (not pd.isna(row['有效锌mg/kg']) and row['有效锌mg/kg'] >10):
+                effectiveX.append('有效锌:超阈值。')
+                effectiveXTar.append('有效锌。')
+            else:
+                effectiveX.append('')
+                effectiveXTar.append('')
+            #(7)有效硼在[0.1, 2] 范围之外的,存疑;
+            if (not pd.isna(row['有效硼mg/kg']) and row['有效硼mg/kg'] <0.1) or (not pd.isna(row['有效硼mg/kg']) and row['有效硼mg/kg'] >2):
+                effectiveP.append('有效硼:超阈值。')
+                effectivePTar.append('有效硼。')
+            else:
+                effectiveP.append('')
+                effectivePTar.append('')
+            #(8)有效钼在[0.03, 1]范围之外的,存疑。
+            if (not pd.isna(row['有效钼mg/kg']) and row['有效钼mg/kg'] <0.03) or (not pd.isna(row['有效钼mg/kg']) and row['有效钼mg/kg'] >1):
+                effectiveMu.append('有效钼:超阈值。')
+                effectiveMutar.append('有效钼。')
+            else:
+                effectiveMu.append('')
+                effectiveMutar.append('')
+        resData = pd.DataFrame({
+            '审核结果': pd.Series(effectiveL) + pd.Series(effectiveT) + pd.Series(effectiveG) +
+                pd.Series(effectiveM) + pd.Series(effectiveCu) + pd.Series(effectiveX) + pd.Series(effectiveP) + pd.Series(
+                    effectiveMu),
+            '异常指标': pd.Series(effectiveLTar) + pd.Series(effectiveTTar) + pd.Series(effectiveGTar) +
+                pd.Series(effectiveMTar) + pd.Series(effectiveCuTar) + pd.Series(effectiveXTar) + pd.Series(effectivePTar) + pd.Series(
+                    effectiveMutar)
+        })
+        return resData
+    except Exception as err:
+        print('土壤指标数据判断出错!请检查soil_metal中判断内容', err)
+
+# 表14  土壤重金属判断
+# 这里风险值和管控值判断 单独写两个函数
+# 风险值
+def risk_value(arr):
+    unnormalValue = []
+
+    for index, row in arr.iterrows():
+        str = ''
+        if row['编号'][6:10] == '0101': # 水田
+            # 镉
+            if (row['pH'] <= 5.5 and row['镉mg/kg'] > 0.3) or (
+                    row['pH'] > 5.5 and row['pH']<= 6.5 and row['镉mg/kg'] > 0.4) or (
+                    row['pH'] >6.5 and row['pH'] <=7.5 and row['镉mg/kg'] > 0.6) or (
+                    row['pH'] > 7.5 and row['镉mg/kg'] > 0.8):
+                str += '镉超污染风险值筛选值。'
+            # 汞
+            if (row['pH'] <= 5.5 and row['汞mg/kg'] > 0.5) or (
+                    row['pH'] > 5.5 and row['pH'] <= 6.5 and row['汞mg/kg'] > 0.5) or (
+                    row['pH'] > 6.5 and row['pH'] <= 7.5 and row['汞mg/kg'] > 0.6) or (
+                    row['pH'] > 7.5 and row['汞mg/kg'] > 1):
+                str += '汞超污染风险值筛选值。'
+            # 砷
+            if (row['pH'] <= 5.5 and row['砷mg/kg'] >30) or (
+                    row['pH'] > 5.5 and row['pH'] <= 6.5 and row['砷mg/kg'] > 30) or (
+                    row['pH'] > 6.5 and row['pH'] <= 7.5 and row['砷mg/kg'] > 25) or (
+                    row['pH'] > 7.5 and row['砷mg/kg'] > 20):
+                str += '砷超污染风险值筛选值。'
+            # 铅
+            if (row['pH'] <= 5.5 and row['铅mg/kg'] > 80) or (
+                    row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铅mg/kg'] > 100) or (
+                    row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铅mg/kg'] > 140) or (
+                    row['pH'] > 7.5 and row['铅mg/kg'] > 240):
+                str += '铅超污染风险值筛选值。'
+            # 铬
+            if (row['pH'] <= 5.5 and row['铬mg/kg'] > 250) or (
+                    row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铬mg/kg'] > 250) or (
+                    row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铬mg/kg'] > 300) or (
+                    row['pH'] > 7.5 and row['铬mg/kg'] >350):
+                str += '铬超污染风险值筛选值。'
+        else:
+            # 镉
+            if (row['pH'] <= 5.5 and row['镉mg/kg'] > 0.3) or (
+                    row['pH'] > 5.5 and row['pH']<= 6.5 and row['镉mg/kg'] > 0.3) or (
+                    row['pH'] >6.5 and row['pH'] <=7.5 and row['镉mg/kg'] > 0.3) or (
+                    row['pH'] > 7.5 and row['镉mg/kg'] > 0.6):
+                str += '镉超污染风险值筛选值。'
+            # 汞
+            if (row['pH'] <= 5.5 and row['汞mg/kg'] > 1.3) or (
+                    row['pH'] > 5.5 and row['pH'] <= 6.5 and row['汞mg/kg'] > 1.8) or (
+                    row['pH'] > 6.5 and row['pH'] <= 7.5 and row['汞mg/kg'] > 2.4) or (
+                    row['pH'] > 7.5 and row['汞mg/kg'] > 3.4):
+                str += '汞超污染风险值筛选值。'
+            # 砷
+            if (row['pH'] <= 5.5 and row['砷mg/kg'] > 40) or (
+                    row['pH'] > 5.5 and row['pH'] <= 6.5 and row['砷mg/kg'] > 40) or (
+                    row['pH'] > 6.5 and row['pH'] <= 7.5 and row['砷mg/kg'] > 30) or (
+                    row['pH'] > 7.5 and row['砷mg/kg'] > 25):
+                str += '砷超污染风险值筛选值。'
+            # 铅
+            if (row['pH'] <= 5.5 and row['铅mg/kg'] > 70) or (
+                    row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铅mg/kg'] > 90) or (
+                    row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铅mg/kg'] > 120) or (
+                    row['pH'] > 7.5 and row['铅mg/kg'] > 170):
+                str += '铅超污染风险值筛选值。'
+            # 铬
+            if (row['pH'] <= 5.5 and row['铬mg/kg'] > 150) or (
+                    row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铬mg/kg'] > 150) or (
+                    row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铬mg/kg'] > 200) or (
+                    row['pH'] > 7.5 and row['铬mg/kg'] > 250):
+                str += '铬超污染风险值筛选值。'
+
+        if (row['pH'] <= 5.5 and row['镍mg/kg'] > 60) or (
+                row['pH'] > 5.5 and row['pH'] <= 6.5 and row['镍mg/kg'] > 70) or (
+                row['pH'] > 6.5 and row['pH'] <= 7.5 and row['镍mg/kg'] > 100) or (
+                row['pH'] > 7.5 and row['镍mg/kg'] > 190):
+            str += '镍超污染风险值筛选值。'
+        unnormalValue.append(str)
+    return unnormalValue
+
+# 管制值
+def control_value(arr):
+    unnormalValue = []
+    for index, row in arr.iterrows():
+        str = ''
+        # 镉
+        if (row['pH'] <= 5.5 and row['镉mg/kg'] > 1.5) or (
+                row['pH'] > 5.5 and row['pH'] <= 6.5 and row['镉mg/kg'] > 2) or (
+                row['pH'] > 6.5 and row['pH'] <= 7.5 and row['镉mg/kg'] > 3) or (
+                row['pH'] > 7.5 and row['镉mg/kg'] > 4):
+            str += '镉超污染风险值管制值。'
+        # 汞
+        if (row['pH'] <= 5.5 and row['汞mg/kg'] > 2) or (
+                row['pH'] > 5.5 and row['pH'] <= 6.5 and row['汞mg/kg'] > 2.5) or (
+                row['pH'] > 6.5 and row['pH'] <= 7.5 and row['汞mg/kg'] > 4) or (
+                row['pH'] > 7.5 and row['汞mg/kg'] > 6):
+            str += '汞超污染风险值管制值。'
+        # 砷
+        if (row['pH'] <= 5.5 and row['砷mg/kg'] > 200) or (
+                row['pH'] > 5.5 and row['pH'] <= 6.5 and row['砷mg/kg'] > 150) or (
+                row['pH'] > 6.5 and row['pH'] <= 7.5 and row['砷mg/kg'] > 120) or (
+                row['pH'] > 7.5 and row['砷mg/kg'] > 100):
+            str += '砷超污染风险值管制值。'
+        # 铅
+        if (row['pH'] <= 5.5 and row['铅mg/kg'] >400) or (
+                row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铅mg/kg'] > 500) or (
+                row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铅mg/kg'] > 700) or (
+                row['pH'] > 7.5 and row['铅mg/kg'] > 1000):
+            str += '铅超污染风险值管制值。'
+        # 铬
+        if (row['pH'] <= 5.5 and row['铬mg/kg'] > 800) or (
+                row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铬mg/kg'] > 850) or (
+                row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铬mg/kg'] > 1000) or (
+                row['pH'] > 7.5 and row['铬mg/kg'] > 1300):
+            str += '铬超污染风险值管制值。'
+        unnormalValue.append(str)
+    return unnormalValue
+def last_metal(arr):
+    try:
+        totalGe = []  # 总镉在范围之外
+        totalGo = []  # 总汞在范围之外
+        totalShen = []  # 总砷在范围之外
+        totalPb = []  # 总铅在范围之外
+        totalG = []  # 总铬在范围之外
+        totalN = []  # 总镍在范围之外
+        # 异常指标
+        totalGeTar = []  # 总镉
+        totalGoTar = []  # 总汞
+        totalShenTar = []  # 总砷
+        totalPbTar = []  # 总铅
+        totalGTar = []  # 总铬
+        totalNTar = []  # 总镍
+        # (1)超过风险筛选值,提示关注
+        overValue = risk_value(arr) # 超过风险筛选值
+        # (2)超过风险管控值,提示重点关注
+        overLimit = control_value(arr)  # 超过风险管控值
+        for index, row in arr.iterrows():
+            # (3)总镉在[0.03, 0.3]范围之外的,存疑
+            if row['镉mg/kg'] < 0.03 or row['镉mg/kg'] > 0.3:
+                totalGe.append('总镉:超阈值。')
+                totalGeTar.append('总镉。')
+            else:
+                totalGe.append('')
+                totalGeTar.append('')
+            # (4)总汞在[0.01, 0.3]范围之外的,存疑
+            if row['汞mg/kg'] < 0.01 or row['汞mg/kg'] > 0.3:
+                totalGo.append('总汞:超阈值。')
+                totalGoTar.append('总汞。')
+            else:
+                totalGo.append('')
+                totalGoTar.append('')
+            # (5)总砷在[0.5, 30]范围之外的,存疑
+            if row['砷mg/kg'] < 0.5 or row['砷mg/kg'] > 30:
+                totalShen.append('总砷:超阈值。')
+                totalShenTar.append('总砷。')
+            else:
+                totalShen.append('')
+                totalShenTar.append('')
+            # (6)总铅在[2, 100]范围之外的,存疑
+            if row['铅mg/kg'] < 2 or row['铅mg/kg'] > 100:
+                totalPb.append('总铅:超阈值。')
+                totalPbTar.append('总铅。')
+            else:
+                totalPb.append('')
+                totalPbTar.append('')
+            # (7)总铬在[0.4, 200]范围之外的,存疑
+            if row['铬mg/kg'] < 0.4 or row['铬mg/kg'] > 200:
+                totalG.append('总铬:超阈值。')
+                totalGTar.append('总铬。')
+            else:
+                totalG.append('')
+                totalGTar.append('')
+            # (8)总镍在[0.3, 100]范围之外的,存疑
+            if row['镍mg/kg'] < 0.3 or row['镍mg/kg'] > 100:
+                totalN.append('总镍:超阈值。')
+                totalNTar.append('总镍。')
+            else:
+                totalN.append('')
+                totalNTar.append('')
+        resData = pd.DataFrame({
+            '审核结果': pd.Series(overValue) + pd.Series(overLimit) + pd.Series(totalGe) +
+                pd.Series(totalGo) + pd.Series(totalShen) + pd.Series(totalPb) + pd.Series(
+                    totalG) + pd.Series(totalN),
+            '异常指标': pd.Series(totalGeTar) + pd.Series(totalGoTar) + pd.Series(totalShenTar) + pd.Series(totalPbTar) + pd.Series(
+                    totalGTar) + pd.Series(totalNTar)
+        })
+        return resData
+    except Exception as err:
+        print('土壤重金属指标数据判断出错!请检查last_metal中判断内容', err)
+

+ 989 - 0
report.py

@@ -0,0 +1,989 @@
+import pandas as pd
+import numpy as np
+import time
+import public as pb
+import openpyxl
+import matplotlib.pyplot as plt
+from scipy.stats import spearmanr
+# import tkinter as tk
+# from tkinter import ttk
+from tkinter import filedialog
+from tkinter import messagebox
+from openpyxl import load_workbook
+from openpyxl.drawing.image import Image as OImage
+import os
+import re
+import ttkbootstrap as ttk
+from ttkbootstrap.constants import *
+from PIL import Image, ImageTk
+from ttkbootstrap.dialogs import Messagebox
+import plotly.graph_objects as go
+import plotly.io as pio
+from sklearn.linear_model import LinearRegression
+from openpyxl.worksheet.hyperlink import Hyperlink
+from scipy.ndimage import gaussian_filter1d
+from scipy.stats import norm
+from plotly.subplots import make_subplots
+import docx
+from docx import Document
+from docx.shared import Inches
+from docx.oxml import OxmlElement, ns
+from docx.shared import Pt, RGBColor
+from docx.oxml.ns import nsdecls, nsmap
+from docx.oxml import parse_xml
+from docx.enum.dml import MSO_THEME_COLOR_INDEX
+from docx import Document
+from docx.opc.constants import RELATIONSHIP_TYPE as RT
+from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT
+from docx.oxml.ns import qn
+from docx.enum.text import WD_ALIGN_PARAGRAPH
+# 显示所有数据
+pd.set_option('display.width', 10000) # 设置字符显示宽度
+pd.set_option('display.max_rows', None) # 设置显示最大行
+pd.set_option('display.max_columns', None) # 设置显示最大列,None为显示所有列
+
+# 设置字体
+# 设置字体 微软雅黑 新罗马 加粗
+plt.rcParams['font.family'] = ['Times New Roman', 'Microsoft YaHei']
+# 设置字体加粗
+font = {'weight': 'bold'}
+plt.rc('font', **font)  # 应用字体设置
+
+
+indexClassificationList = {
+    '物理指标': ['pH', '土壤质地', '土壤容重1(g/cm³)', '土壤容重2(g/cm³)', '土壤容重3(g/cm³)',	'土壤容重4(g/cm³)',	'土壤容重平均值(g/cm³)',
+                 '2~0.2mm颗粒含量', '0.2~0.02mm颗粒含量',	'0.02~0.002mm颗粒含量',	'0.002mm以下颗粒含量', '水稳>5mm(%)',	'水稳3mm~5mm(%)',
+                 '水稳2mm~3mm(%)',	'水稳1mm~2mm(%)',	'水稳0.5mm~1mm(%)',	'水稳0.25mm~0.5mm(%)',	'水稳性大团聚体总和(%)', '洗失量(吸管法需填)', '风干试样含水量(分析基)'],
+    '常规养分指标': ['有机质', '全氮', '全磷', '全钾', '有效磷', '速效钾', '有效硫', '有效硼', '有效铁', '有效锰', '有效铜', '有效锌', '有效钼', '有效硅', '缓效钾'],
+    '一般化学性指标': ['阳离子交换量', '交换性盐基总量', '交换性钙', '交换性镁', '交换性钠', '交换性钾', '全盐量', '电导率',
+                       '水溶性Na⁺含量', '水溶性K⁺含量',	'水溶性Ca²⁺含量',	'水溶性Mg²⁺含量',	'水溶性Cl⁻含量', '水溶性CO₃²⁻含量','水溶性HCO₃⁻含量',
+                       '水溶性SO₄²⁻含量', '离子总量', '碳酸钙',
+                       '游离铁', '全硫', '全锰', '全锌', '全铜', '全钼', '全硼', '全硒', '全铝', '全硅', '全铁', '全钙', '全镁'],
+    '重金属指标': ['总汞', '总砷', '总铅', '总镉', '总铬', '总镍']
+}
+
+# 可交互绘图函数
+def getInteractiveImg(x,y,label,x1,y1,label1,x2,y2,label2,url,name,xLabel,YLabel,numArr):
+    # coef, p_value = spearmanr(x, y)
+    # 绘制数据散点图
+    fig = go.Figure(data=go.Scatter(
+        x=x,
+        y=y,
+        text=numArr.to_numpy(),
+        mode='markers', name=label,
+        marker=dict(
+            size=10,  # 点的大小
+            color='blue',  # 点的颜色
+        ))
+    )
+    # 设置图表布局
+    fig.update_layout(
+                      title={
+                          'text': f"{name}",
+                          'xanchor': 'center',  # 控制水平对齐,可选'left', 'center', 'right'
+                          'yanchor': 'bottom',  # 控制垂直对齐,可选'top', 'middle', 'bottom'
+                          'x': 0.5,  # 控制标题的水平位置,0.5代表中心,可以是小数(相对位置)或整数(像素位置)
+                          'y': 0.9  # 控制标题的垂直位置,0.9代表底部,可以是小数或整数
+                      },
+                      xaxis_title=xLabel,
+                      yaxis_title=YLabel)
+    if label == 'pH':
+        ph_y_f = [7.5 for _ in x]
+        ph_y_s = [8.0 for _ in x]
+        fig.add_trace(go.Scatter(x=x, y=ph_y_f, mode='lines', name='pH = 7.5', line=dict(
+            width=1.5,
+            color='#339933',
+            dash='dash'  # 设置虚线样式
+        )))
+        fig.add_trace(go.Scatter(x=x, y=ph_y_s, mode='lines', name='pH = 8.0', line=dict(
+            width=2.5,
+            color='#339933',
+            dash='dash'  # 设置虚线样式
+        )))
+    if len(x1) > 0 and len(y1) > 0:
+        fig.add_trace(go.Scatter(x=x1, y=y1, mode='markers', name=label1, text=numArr.to_numpy(),
+                                 marker=dict(
+                                    size=10,        # 点的大小
+                                    color='red',    # 点的颜色
+                                    symbol='hourglass'
+                                )))
+    if len(x2) > 0 and len(y2) > 0:
+        fig.add_trace(go.Scatter(x=x2, y=y2, mode='markers', name=label2, text=numArr.to_numpy(),
+                                marker=dict(
+                                    size=10,        # 点的大小
+                                    color='green',    # 点的颜色
+                                    symbol='triangle-up'  # 点的形状,这里设置为正方形
+                                )))
+    # model = LinearRegression()
+    # model.fit(x.to_numpy().reshape(-1, 1), y)  # 用x的平方作为特征值
+    # y_pred = model.predict(x.to_numpy().reshape(-1, 1))
+    # fig.add_trace(go.Scatter(x=x, y=y_pred, mode='lines', name='拟合直线'))
+
+    html_file_path = f"{url}/{name}.html"
+    pio.write_html(fig, file=html_file_path, auto_open=False)
+    # 同时保存一份图片
+    pio.write_image(fig, f"{url}/{name}.png")
+    # 在文档中中插入html
+    # workbook = load_workbook(filename=fileUrl)
+    # # 选择一个工作表
+    # ws = workbook[sheetName]
+    # # 将 HTML 内容作为富文本写入单元格
+    # ws[loc] = '=HYPERLINK("file:///{0}","点击查看统计图")'.format(html_file_path)
+    # workbook.save(fileUrl)
+
+
+
+# 循环确定数据属于哪一个类型
+def getDataType(data, list):
+
+    for item in list:
+        if str(str(data['原样品编号'])[6:10]) in list[item]:
+           data['土地类型归类'] = item
+
+    return data
+
+# 1. 统计样品数量 分类统计:耕地:0101 0102 0103 园地:0201 0202 0203 0204  林地:0301 0302 0303 0304 0305 0306 0307 草地:0401 0402 0403 0404
+def getSimpleNum(data):
+    """
+    :param simpleData: 样品数据
+    :return:
+    """
+    typeList = {
+        '耕地园地': ['0101', '0102', '0103', '0201', '0202', '0203', '0204'],
+        '林地草地': ['0301', '0302', '0303', '0304', '0305', '0306', '0307', '0401', '0402', '0403', '0404'],
+        '商服用地': ['0501', '0502', '0503', '0504', '0505', '0506', '0507'],
+        '工矿仓储用地': ['0601', '0602', '0603', '0604'],
+        '住宅用地': ['0701', '0702'],
+        '公共管理与公共服务用地': ['0801', '0802', '0803', '0804', '0805', '0806', '0807', '0808', '0809', '0810'],
+        '特殊用地': ['0901', '0902', '0903', '0904', '0905', '0906'],
+        '交通运输用地': ['1001', '1002', '1003', '1004', '1005', '1006', '1007', '1008', '1009'],
+        '水域及水利设施用地': ['1101', '1102', '1103', '1104', '1105', '1106', '1107', '1108', '1109', '1110'],
+        '其他土地': ['1201', '1202', '1203', '1204', '1205', '1206', '1207']
+    }
+    # 根据耕地园地、林地草地分类数据,统计不同类型数据数量,生成表格
+    newData = pd.DataFrame({})
+    for index, row in data.iterrows():
+        newRow = getDataType(row, typeList)
+        newData =newData._append(newRow)
+
+    # 按照土地类型归类 分类计数
+    grouped_df = newData.groupby('土地类型归类')
+    counts = grouped_df.size()
+    resData = pd.DataFrame({})
+
+    for group_name, group_data in grouped_df:
+        # 附表:数量总体统计数据
+        res = {
+            '类型': group_name,
+            '样品编号': group_data['样品编号'].to_list(),
+            '数量': counts[group_name],
+            '合计': counts.sum()
+        }
+        newRes = pd.DataFrame(res)
+        resData = resData._append(newRes)
+
+    return {
+        'sData': counts, # 统计数量
+        'allData': resData # 附表总数
+    }
+
+# 2.小数修改:进行中
+def is_one_decimal_place(num): # 判断是否保留一位小数
+    return str(num)[:-2] == '10' or str(num).count('.') == 1 and len(str(num).split('.')[1]) == 1
+
+def has_two_decimals(num): # 判断是否保留了两位小数
+    return str(num)[-4:] == ".00" or str(num).count(".") == 1 and len(str(num).split(".")[1]) == 2
+
+def three_decimal(num):
+    # 不超过三位有效数字
+    num = str(num)
+    num = num.replace('.', '')
+    numLen = 0
+    stripped_s = num.lstrip('0')
+    if stripped_s and stripped_s[0].isdigit():
+        index = num.index(stripped_s[0])  # 加上去除的0的个数
+        numLen = len(num[index:])
+      # 字符串全为0或不包含数字时
+    return numLen
+
+def is_less_than_three_decimals(number): # 不超过3位小数
+    # 转换为字符串
+    number_str = str(number)
+    # 分离整数部分和小数部分
+    integer_part, decimal_part = number_str.split('.') if '.' in number_str else (number_str, '')
+    # 判断小数部分是否不超过三位
+    return len(decimal_part) <= 3
+
+# 保留3位小数
+def is_three_decimal(number):
+    number_str = str(number)
+    # 分离整数部分和小数部分
+    integer_part, decimal_part = number_str.split('.') if '.' in number_str else (number_str, '')
+    # 判断小数部分是否不超过三位
+    return len(decimal_part) == 3
+
+def highlight_condition(s):
+    if s['数据审核结果'] != '' and not pd.isna(s['数据审核结果']):
+        return ['background-color: #99CC99']*len(s)
+    else:
+        return ['']*len(s)
+
+def getNum(data, url):
+    # 读取数据 处理每一项小数保留问题
+    oneData = ['2~0.2mm颗粒含量','0.2~0.02mm颗粒含量','0.02~0.002mm颗粒含量','0.002mm以下颗粒含量', '洗失量(吸管法需填)',
+               '水稳>5mm','水稳3mm~5mm','水稳2mm~3mm','水稳1mm~2mm','水稳0.5mm~1mm','水稳0.25mm~0.5mm','水稳性大团聚体总和'
+               ]
+    twoData = ['土壤容重1(g/cm³)','土壤容重2(g/cm³)','土壤容重3','土壤容重4','土壤容重平均值','pH']
+    threeData = ['电导率','水溶性钠离子','水溶性钾离子','水溶性钙离子','水溶性镁离子','水溶性碳酸根','水溶性碳酸氢根','水溶性硫酸根','水溶性氯根','离子总量'] # 3位有效数字
+    twoDataToThree = ['有机质','全氮','全磷','全钾','全硫','全硼','全硒','全铁'] #保留2位小数,最多不超过3位有效数字
+    threeDataToThree = ['有效钼', '总汞']
+    changeDataList = ['阳离子交换量', '交换性盐基总量', '交换性钙', '交换性镁', '交换性钠', '交换性钾'] # <10 2位小数 >=10 3位有效数字
+    cationDataList = ['全锰', '全铜', '全锌', '速效钾', '缓效钾', '有效硅', '总铅', '总镉', '总铬', '总镍'] # <1000 2位小数 不超过3位有效数字 >=1000 保留整数
+    needData = data.iloc[:, 7:]
+    if '土壤质地' in needData.columns:
+        del needData['土壤质地']
+    needData = needData.apply(pd.to_numeric, errors='coerce')
+    checkDataRes = []
+    for index, row in needData.iterrows():
+        str = ''
+        for item in row.index:
+            if item in oneData and (not pd.isna(row[item])) and not is_one_decimal_place(row[item]):
+                str += f"{item}应保留一位小数。"
+            if item in twoData and (not pd.isna(row[item])) and not has_two_decimals(row[item]):
+                str += f"{item}应保留两位小数。"
+            if item in threeData and (not pd.isna(row[item])) and three_decimal(row[item]) != 3:
+                str += f"{item}应保留三位有效数字。"
+            if item in twoDataToThree and (not pd.isna(row[item])) and (not has_two_decimals(row[item]) or three_decimal(row[item]) > 3):
+                str += f"{item}应保留两位小数且不超过三位有效数字。"
+            if item in threeDataToThree and (not pd.isna(row[item])) and (not is_less_than_three_decimals(row[item]) or three_decimal(row[item]) != 3 ):
+                str += f"{item}应保留三位有效数字且不超过三位小数。"
+            if item in changeDataList and (not pd.isna(row[item])) and (row[item] < 10) and not has_two_decimals(row[item]):
+                str += f"{item}应保留两位小数。"
+            if item in changeDataList and (not pd.isna(row[item])) and (row[item] >= 10) and three_decimal(row[item]) != 3:
+                str += f"{item}应保留三位有效数字。"
+            if item == '碳酸钙' and (not pd.isna(row[item])) and not isinstance(row[item], int):
+                str += f"{item}应为整数。"
+            if item == '全盐量' and (not pd.isna(row[item])) and not is_three_decimal(row[item]):
+                str += f"{item}应保留3位小数。"
+            if item in cationDataList and (not pd.isna(row[item])) and (row[item] < 1000) and (not has_two_decimals(row[item]) or three_decimal(row[item]) > 3):
+                str += f"{item}保留2位小数且不超过三位有效数字。"
+            if item in cationDataList and (not pd.isna(row[item])) and (row[item] >= 1000) and not isinstance(row[item], int):
+                str += f"{item}应为整数。"
+        checkDataRes.append(str)
+    data['数据审核结果'] = checkDataRes
+    # 对审核结果有问题的数据进行标绿
+    resData = data.style.apply(highlight_condition, axis=1)
+    # 数据写入表格
+    with pd.ExcelWriter( f'{url}/数值修约审核.xlsx', engine='openpyxl') as writer:
+        resData.to_excel(writer, index=False, sheet_name='数值修约')
+
+# getNum('')
+# 3.计算所有指标的频度信息 已完成
+def getFrequencyInformation(data, url):
+    if '数据审核结果' in data.columns:
+        del data['数据审核结果']
+    if '母岩' in data.columns:
+        del data['母岩']
+    #统计样品数量 计算最大值 最小值 中位数 平均值 标准差
+    needData = data.iloc[:, 7:]
+    if '土壤质地' in needData.columns:
+        del needData['土壤质地']
+
+    needData = needData.apply(pd.to_numeric, errors="coerce")
+    resData = pd.DataFrame({})
+    for item in needData.columns:
+        if item == '总砷':
+            print(needData[item])
+        min_value = needData[item].min() # 最大值
+        max_value = needData[item].max() # 最小值
+        median_value = needData[item].median()  # 中位数
+        mean_value = needData[item].mean()  # 平均数
+        std_value = needData[item].std()  # 标准差
+        resData[item] = [min_value, max_value, median_value, mean_value, std_value]
+
+    index_value = ['最小值', '最大值', '中位数', '平均数', '标准差']
+    # 汇总数据
+    resData.index = index_value
+    data_res = round(resData, 2)
+    data_res = data_res.rename_axis('频度分析')
+    # data_res = data_res.transpose()
+    # data_res = data_res.reset_index()
+    # data_res.columns = ['指标名称', '最小值', '最大值', '中位数', '平均数', '标准差']
+    print('频度分析---', data_res)
+    return data_res
+    # 数据写入表格
+    # with pd.ExcelWriter(f'{url}/频度信息.xlsx', engine='openpyxl') as writer:
+    #     data_res.to_excel(writer, sheet_name='频度信息')
+
+# getFrequencyInformation('')
+# 4. 绘制每个指标的累积频率图
+def getMap(data, title, unit, url):
+    data = data.dropna()
+    if len(data) != 0: # 指标无数据 不进行绘图
+        min = data.min()
+        max = data.max()
+        # 计算直方图
+        bins = np.linspace(min - 1, max + 1, 30, endpoint=True)
+        hist, bin_edges = np.histogram(data, bins=bins)
+        cumulative_hist = np.cumsum(hist)
+        # 计算拟合曲线
+        p1 = np.polyfit(bin_edges[1:], hist, 2)
+        p2 = np.poly1d(p1)
+        # 计算累计频率
+        cumulative_freq = cumulative_hist / cumulative_hist.max()
+        # fig, ax1 = plt.subplots()
+        fig = make_subplots(specs=[[{"secondary_y": True}]])
+        if title == 'pH':
+            fig.add_trace(go.Histogram(x=data, name="频数", nbinsx = 17, xbins = dict(start=0, end=8.5, size=0.5)), secondary_y=True)
+        else:
+            fig.add_trace(go.Histogram(x=data, name="频数"), secondary_y=True)
+        # 绘制直方图 color="#ffc798" #a4464b #b1a9ab
+        # fig = go.Figure(data=[go.Histogram(x=data, name="频数")])
+        # 设置标题和其他格式
+        fig.update_layout(
+            title={
+                'text': f"{title}统计图",
+                'xanchor': 'center',  # 控制水平对齐,可选'left', 'center', 'right'
+                'yanchor': 'bottom',  # 控制垂直对齐,可选'top', 'middle', 'bottom'
+                'x': 0.5,  # 控制标题的水平位置,0.5代表中心,可以是小数(相对位置)或整数(像素位置)
+                'y': 0.9  # 控制标题的垂直位置,0.9代表底部,可以是小数或整数
+            },
+            xaxis_title=f"{title}{unit}",
+            yaxis_title='频次',
+            bargap=0.2,  # 相邻位置坐标的钢筋之间的间隙
+            bargroupgap=0.1
+        )
+        # ax1.hist(data, bins=bins, rwidth=0.8, zorder=1, label="频数")
+        # ax2 = ax1.twinx()
+        # ax2.plot(bin_edges[1:], cumulative_freq, zorder=10, color="#a4464b", label="累积频率 ")
+        fig.add_trace(go.Scatter(x=bin_edges[1:], y=cumulative_freq *100, mode='lines', name='累积频率',line=dict(width=2), yaxis='y2',
+                                 marker=dict(
+                                     color='red',  # 点的颜色
+                                     symbol='hourglass'
+                                 )), secondary_y=False)
+        # 绘制正态分布曲线
+        # 估计正态分布参数
+        mu = data.mean()
+        sigma = data.std()
+        # 创建正态分布对象
+        dist = norm(mu, sigma)
+        # 计算要绘制的x值
+        x = np.linspace(bin_edges.min(), bin_edges.max(), 100)
+        p = norm.pdf(x, mu, sigma)
+        # ax3 = ax1.twinx()
+        # # ax3.plot(bin_edges[1:], y_smoothed, label='拟合曲线', color="#333")
+        # #label = 'N({:.2f}, {:.2f}^2)'.format(mu, sigma)
+        # ax3.plot(x, dist.pdf(x), color="#333", label='拟合曲线')
+
+        fig.add_trace(go.Scatter(x=x, y=p*100, mode='lines', yaxis='y2', name='拟合曲线', line=dict(width=2)), secondary_y=False)
+        fig.update_layout(
+            title={
+                'text': '指标累积频率分析图',
+                'xanchor': 'center',  # 控制水平对齐,可选'left', 'center', 'right'
+                'yanchor': 'bottom',  # 控制垂直对齐,可选'top', 'middle', 'bottom'
+                'x': 0.5,  # 控制标题的水平位置,0.5代表中心,可以是小数(相对位置)或整数(像素位置)
+                'y': 0.9  # 控制标题的垂直位置,0.9代表底部,可以是小数或整数
+            },
+            yaxis_title='累积频率(%)',  # 设置Y1轴标签
+            yaxis2_title='频数'
+                          )
+        maxData = 110
+        if p.max()*100 >100:
+            maxData = p.max()*100
+        fig.update_yaxes(range=[0, maxData], row=1, col=1, secondary_y=False)
+        html_file_path = f"{url}/{title}分析图.html"
+        html_file_path = html_file_path.replace('(g/cm³)','')
+        html_file_path = html_file_path.replace('(%)', '')
+        html_file_path = html_file_path.replace('>', '')
+        pio.write_html(fig, file=html_file_path, auto_open=False)
+        title = title.replace('(g/cm³)', '')
+        title = title.replace('(%)', '')
+        title = title.replace('>', '')
+        pio.write_image(fig, f"{url}/{title}分析图.png")
+
+
+def getFrequencyImage(data, url):
+    unitList = {
+        'g/cm3': ['土壤容重1(g/cm³)','土壤容重2(g/cm³)',	'土壤容重3(g/cm³)',	'土壤容重4(g/cm³)','土壤容重平均值(g/cm³)'],
+        '%': ['土壤机械组成','全铝', '全硅', '全铁', '全钙', '全镁', '水稳>5mm(%)','水稳3mm~5mm(%)',	'水稳2mm~3mm(%)',	'水稳1mm~2mm(%)',	'水稳0.5mm~1mm(%)',	'水稳0.25mm~0.5mm(%)',	'水稳性大团聚体总和(%)'],
+        'g/kg': ['有机质', '全氮', '全磷', '全钾', '水溶性盐总量', '离子总量', '碳酸钙', '游离铁', '全硫'],
+        'mg/kg': ['有效磷', '速效钾', '有效硫', '有效硼', '有效铁', '有效锰', '有效铜', '有效锌', '有效钼', '有效硅', '缓效钾', '全锰',
+                '全锌', '全铜', '全钼', '全硼', '全硒', '总汞', '总砷', '总铅', '总镉', '总铬', '总镍'],
+        'cmol/kg': ['阳离子交换量', '交换性盐基总量', '交换性钙', '交换性镁', '交换性钠', '交换性钾']
+    }
+    # 绘制图形
+    needData = data.iloc[:, 7:] #这里有可能需要修改
+    if '土壤质地' in needData.columns:
+        del needData['土壤质地']
+    needData = needData.apply(pd.to_numeric, errors="coerce")
+    for item in needData.columns:
+        # newData = needData[item].dropna()
+        if len(needData) > 0:
+            label = ''
+            for i in unitList:
+                if item in unitList[i]:
+                    label = i
+            getMap(needData[item], item, label, url)
+
+# 公共函数 判断指标完整性
+# def checkAllNames(data, list):
+
+    # for item in list:
+    #     if data[item] != '未检测' and data[item] != '/': # 未检测的值可以忽略 空值
+    #         if pd.isna(data[item]): # 表示值缺失
+
+
+# 5. 检测指标完整性
+def getDataComplete(data):
+    # 根据类型:耕地园地表层土壤样品,耕地园地剖面土壤样品,林地草地表层土壤样品,林地草地剖面土壤样品,水稳定性大团聚体样品
+    # 耕地园地样品列表  有效硅(水田才有)
+    cultivatedLandandfieldList = ['风干试样含水量(分析基)', '洗失量(吸管法需填)', '土壤质地', '土壤容重1(g/cm³)',	'土壤容重2(g/cm³)',	'土壤容重3(g/cm³)',	'土壤容重4(g/cm³)',	'土壤容重平均值(g/cm³)'
+        , '2~0.2mm颗粒含量',	'0.2~0.02mm颗粒含量',	'0.02~0.002mm颗粒含量', 	'0.002mm以下颗粒含量'
+        , '水稳>5mm(%)',	'水稳3mm~5mm(%)','水稳2mm~3mm(%)',	'水稳1mm~2mm(%)','水稳0.5mm~1mm(%)','水稳0.25mm~0.5mm(%)',	'水稳性大团聚体总和(%)'
+        , 'pH', '阳离子交换量', '交换性盐基总量', '交换性钙', '交换性镁', '交换性钠', '交换性钾',
+        '全盐量', '电导率', '水溶性Na⁺含量', '水溶性K⁺含量', '水溶性Ca²⁺含量', '水溶性Mg²⁺含量', '水溶性Cl⁻含量', '水溶性CO₃²⁻含量',
+        '水溶性HCO₃⁻含量', '水溶性SO₄²⁻含量', '离子总量', '有机质', '全氮', '全磷', '全钾', '有效磷', '速效钾', '缓效钾', '有效硫', '有效铁',
+        '有效锰', '有效铜', '有效锌', '有效硼', '有效钼', '总汞', '总砷', '总铅', '总镉', '总铬', '总镍']
+    # 林地草地样品列表
+    woodlandandGrassList = ['风干试样含水量(分析基)', '洗失量(吸管法需填)', '土壤质地', '土壤容重1(g/cm³)',	'土壤容重2(g/cm³)',	'土壤容重3(g/cm³)',	'土壤容重4(g/cm³)',	'土壤容重平均值(g/cm³)', '2~0.2mm颗粒含量','0.2~0.02mm颗粒含量',	'0.02~0.002mm颗粒含量', '0.002mm以下颗粒含量', 'pH', '阳离子交换量', '交换性盐基总量', '交换性钙', '交换性镁', '交换性钠', '交换性钾', '有机质',
+                    '全氮', '全磷', '全钾', '有效磷', '速效钾',]
+
+
+    # 其他样品列表 剖面
+    # '耕地': ['0101', '0102', '0103'],
+    # '园地': ['0201', '0202', '0203', '0204'],
+    # '林地': ['0301', '0302', '0303', '0304', '0305', '0306', '0307'],
+    # '草地': ['0401', '0402', '0403', '0404'],
+    # 根据土地利用类型 判断指标是否完整 不完整的数据提取出来 这里规则无法确定 先放着吧
+
+    # 统计所有数据中 各指标的数量
+    resData = getSimpleNum(data)
+    yxg = 0
+    for index, row in data.iterrows():
+        if str(str(row['原样品编号'])[6:10]) == '0101':
+            yxg += 1
+    data = data.replace('未检测', np.nan)
+    if '序号' in data.columns:
+        del data['序号']
+    if '原样品编号' in data.columns:
+        del data['原样品编号']
+    if '样品编号' in data.columns:
+        del data['样品编号']
+    if '地理位置' in data.columns:
+        del data['地理位置']
+    if '母质' in data.columns:
+        del data['母质']
+    if '土壤类型' in data.columns:
+        del data['土壤类型']
+    if '土地利用类型' in data.columns:
+        del data['土地利用类型']
+    # 根据指标排序
+    counts = data.count()
+    # 根据土地类型统计样本数
+    countData = {
+        '耕地园地': resData['sData']['耕地园地'] if '耕地园地' in resData['sData'].index else 0,
+        '林地草地': resData['sData']['林地草地'] if '林地草地' in resData['sData'].index else 0,
+        '其他': 0,
+        '有效硅': yxg
+    }
+    needNumList = []
+    for item in data.columns:
+        # 判断指标是否属于耕地园地、林地草地数组
+        if item == '有效硅':
+            needNumList.append(countData['有效硅'])
+        elif (item in cultivatedLandandfieldList) and (item in woodlandandGrassList):
+            needNumList.append(countData['耕地园地'] + countData['林地草地'])
+        elif (item in cultivatedLandandfieldList) and (item not in woodlandandGrassList):
+            needNumList.append(countData['耕地园地'])
+        elif (item not in cultivatedLandandfieldList) and (item in woodlandandGrassList):
+            needNumList.append(countData['林地草地'])
+        elif (item not in cultivatedLandandfieldList) and (item not in woodlandandGrassList):
+            needNumList.append(0)
+        else:
+            needNumList.append(0)
+    counts = counts.to_frame()
+    counts['应测数量'] = needNumList
+    return counts
+
+
+
+# 6.指标名称与实际检测样品数量统计表,统计样品数量和指标检测数量
+def getCheckNum():
+    # 统计每个指标的有值的数量,水溶性盐分总量大于1g/kg的 统计八大离子的检测量
+    resData = ''
+    return resData
+
+
+# 过滤特殊字符
+def filter_special_characters(s):
+    s = str(s)
+    return re.sub(r'[^a-zA-Z\u4e00-\u9fa5\d]', '', s)
+
+# 7.检测方法
+def checkMethod(data, url):
+    # 各指标的检测标准方法
+    checkData = {
+        '土壤容重' : '《土壤检测 第4部分:土壤容重的测定》(NY/T 1121.4—2006) 环刀法',
+        '机械组成' : '《土壤分析技术规范》(第二版), 5.1 吸管法',
+        '土壤水稳性大团聚体': '《土壤检测 第19部分:土壤水稳定大团聚体组成的测定》(NY/T 1121.19—2008)筛分法',
+        'pH检测方法': '《土壤检测 第2部分:土壤pH的测定》(NY/T 1121.2—2006) 电位法',
+        '水溶性盐类(水溶性盐总量、电导率、水溶性钠离子、钾离子、钙离子、镁离子、碳酸根、碳酸氢根、硫酸根、氯根)': '《森林土壤水溶性盐分分析》(LY/T 1251—1999)(浸提液中钙、镁、钾、钠离子的测定采用等离子体发射光谱法,硫酸根和碳酸根的测定增加离子色谱法) 质量法',
+        '全氮': '《土壤检测 第24部分:土壤全氮的测定 自动定氮仪法》(NY/T 1121.24—2012) 自动定氮仪法',
+        '全磷': '《森林土壤磷的测定》(LY/T 1232—2015)(详见本规范培训教材) 酸消解—电感耦合等离子体发射光谱法',
+        '全钾': '《森林土壤钾的测定》(LY/T 1234—2015) 酸消解一电感耦合等离子体发射光谱法',
+        '全铁': '《固体废物22种金属元素的测定》(HJ 781—2016) 酸消解—电感耦合等离子体发射光谱法',
+        '全锰': '《固体废物22种金属元素的测定》(HJ 781—2016) 酸消解—电感耦合等离子体发射光谱法',
+        '全钼': '《固体废物 金属元素的测定 电感耦合等离子体质谱法》(HJ 766—2015) 酸消解—电感耦合等离子体质谱法',
+        '全铝': '《固体废物 22种金属元素的测定 电感耦合等离子体发射光谱法》(HJ 781—2016) 酸消解-电感耦合等离子体发射光谱法',
+        '全硅': '《土壤和沉积物 11种元素的测定 碱熔—电感耦合等离子体发射光谱法》(HJ 974—2018) 碱熔一电感耦合等离子体发射光谱法	',
+        '全钙': '《固体废物 22种金属元素的测定 电感耦合等离子体发射光谱法》(HJ 781—2016) 酸消解—电感耦合等离子体发射光谱法',
+        '全镁': '《固体废物 22种金属元素的测定 电感耦合等离子体发射光谱法》(HJ 781—2016) 酸消解—电感耦合等离子体发射光谱法',
+        '速效钾': '《土壤 速效钾和缓效钾含量的测定》(NY/T 889—2004) 乙酸铵浸提—火焰光度法',
+        '缓效钾': '《土壤 速效钾和缓效钾含量的测定》(NY/T 889—2004) 热硝酸浸提—火焰光度法',
+        '有效硅': '《土壤检测第15部分:土壤有效硅的测定》(NY/T 1121.15-2006) 柠檬酸浸提-硅钼蓝比色法',
+        '有效硼': '土壤样品制备与检测技术规范培训教材 沸水提取-电感耦合等离子体发射光谱法',
+        '有效钼': '《土壤检测 第9部分:土壤有效钼的测定》(NY/T 1121.9-2023) 草酸-草酸铵浸提-电感耦合等离子体质谱法',
+        '游离铁': '《土壤分析技术规范》(第二版),19.1游离铁(Fed)的测定(DCB法) 连二亚硫酸钠-柠檬酸钠-重 碳酸提-邻菲罗啉比色法',
+        '总砷': '《土壤质量 总汞、总砷、总铅的测定 原子荧光法第2部分:土壤中总砷的测定》(GB/T22105.2-2008) 原子荧光法',
+        '总铅': '《固体废物 金属元素的测定电感耦合等离子体质谱法》(HJ766-2015) 酸消解-电感耦合等离子体质谱法',
+        '总镉': '《固体废物 金属元素的测定电感耦合等离子体质谱法》(HJ766-2015) 酸消解-电感耦合等离子体质谱法',
+        '总铬': '《固体废物 金属元素的测定电感耦合等离子体质谱法》(HJ766-2015) 酸消解-电感耦合等离子体质谱法',
+        '总镍': '《固体废物 金属元素的测定电感耦合等离子体质谱法》(HJ766-2015) 酸消解-电感耦合等离子体质谱法'
+    }
+    checkDBData = {
+        '有机质': ['《土壤检测 第6部分:土壤有机质的测定》(NY/T 1121.6—2006) 重铬酸钾氧化—容量法',
+                   '土壤中总碳和有机质的测定元素分析仪法(农业行业标准报批稿) 元素分析仪法'],  # 两种方法都可以
+        '全硫': ['《土壤检测 第2部分:土壤全硫的测定》(NY/T 1104—2006) 硝酸镁氧化-硫酸钡比浊法',
+                 '燃烧红外光谱法(本规范培训教材)'],
+        '全硼': ['《土壤分析技术规范》(第二版),18.1土壤全硼的测定 碱熔-姜黄素-比色法',
+                 '《土壤分析技术规范》(第二版),18.1土壤全硼的测定 碱熔-等离子体发射光谱法'],
+        '全铜': ['《固体废物 金属元素的测定电感耦合等离子体质谱法》(HJ766-2015) 酸消解-电感耦合等离子体质谱法',
+                 '《固体废物 22种金属元素的测定电感耦合等离子体发射光谱法》(HJ781-2016) 酸消解-电感耦合等离子体发射光谱法'],
+        '全锌': ['《固体废物 金属元素的测定电感耦合等离子体质谱法》(HJ766-2015) 酸消解一电感耦合等离子体质谱法',
+                 '《固体废物 22种金属元素的测定 电感耦合等离子体发射光谱法》(HJ 781—2016) 酸消解—电感耦合等离子体发射光谱法'],
+        '可交换酸度': '《土壤分析技术规范》(第二版), 11.2 土壤交换性酸的测定 氯化钾交换—中和滴定法',  # ph<6
+        '碳酸钙': '《土壤分析技术规范》(第二版), 15.1 土壤碳酸盐的测定 气量法',  # ph>7
+        '总汞': ['《土壤质量 总汞、总砷、总铅的测定原子荧光法 第1部分:土壤中总汞的测定》(GB/T22105.1-2008) 原子荧光法',
+                 '《土壤和沉积物总汞的测定 催化热解/冷原子吸收分光光度法》(HJ923-2017) 催化热解-冷原子吸收分光光度法'],
+        '有效铁': [
+            '《土壤有效态锌、锰、铁、铜含量的测定 二乙三胺五乙酸(DTPA)浸提法》(NY/T8902004) DTPA 浸提-原子吸收分光光度法',
+            '《土壤有效态锌、锰、铁、铜含量的测定 二乙三胺五乙酸(DTPA)浸提法》(NY/T8902004) DTPA 浸提-电感耦合等离子体发射光谱法'],
+        '有效锰': [
+            '《土壤有效态锌、锰、铁、铜含量的测定 二乙三胺五乙酸(DTPA)浸提法》(NY/T8902004) DTPA 浸提-原子吸收分光光度法',
+            '《土壤有效态锌、锰、铁、铜含量的测定 二乙三胺五乙酸(DTPA)浸提法》(NY/T8902004) DTPA浸提-电感耦合等离子体发射光谱法'],
+        '有效铜': [
+            '《土壤有效态锌、锰、铁、铜含量的测定 二乙三胺五乙酸(DTPA)浸提法》(NY/T8902004) DTPA 浸提-原子吸收分光光度法',
+            '《土壤有效态锌、锰、铁、铜含量的测定 二乙三胺五乙酸(DTPA)浸提法》(NY/T8902004) DTPA 浸提-电感耦合等离子体发射光谱法'],
+        '有效锌': [
+            '《土壤有效态锌、锰、铁、铜含量的测定 二乙三胺五乙酸(DTPA)浸提法》(NY/T8902004) DTPA 浸提-原子吸收分光光度法',
+            '《土壤有效态锌、锰、铁、铜含量的测定 二乙三胺五乙酸(DTPA)浸提法》(NY/T8902004) DTPA 浸提-电感耦合等离子体发射光谱法'],
+    }
+    checkPHData = {
+        '阳离子交换量': ['《土壤分析技术规范》(第二版), 12.2 乙酸铵交换法',
+                         '《土壤分析技术规范》(第二版), 12.1 EDTA—乙酸铵盐交换法'],  # ph<=7.5 ph>7.5
+        '交换性盐基总量、交换性钾、交换性钠、交换性钙、交换性镁': [
+            '《土壤分析技术规范》(第二版), 13.1 酸性和中性土壤交换性盐基组分的测定(乙酸铵交换法)(交换性钙、镁、钾、钠离子的测定增加等离子体发射光谱法) 乙酸铵交换法等',
+            '《石灰性土壤交换性盐基及盐基总量的测定》(NY/T 1615-2008)(交换液中钾、钠、钙、镁离子的测定增加等离子体发射光谱法) 氯化铵-乙醇交换法等'],
+        # ph<=7.5 ph>7.5
+        '有效磷': ['《土壤检测 第7部分:土壤有效磷的测定》(NY/T 1121.7—2014) 氟化铵-盐酸溶液浸提一钼锑抗比色法',
+                   '《土壤检测 第7部分:土壤有效磷的测定》(NY/T 1121.7—2014) 碳酸氢钠溶液—钼锑抗比色法'],  # ph<6.5 ph>=6.5
+        '有效硫': ['《土壤检测第14部分:土壤有效的测定》NY/T 1121.14-2023) 磷酸盐-乙酸溶液浸提-电感耦合等离子体发射光谱法',
+                   '《土壤检测第14部分:土壤有效的测定》(NY/T 1121.14-2023) 氯化钙浸提一电感耦合等离子体发射光谱法'],
+        # ph<7.5 ph>=7.5
+
+    }
+    checkDataKey =  [key for key in checkData]
+    checkDBDataKey = ['有机质', '全硫', '全硼', '全铜', '全锌', '可交换酸度', '碳酸钙', '总汞', '有效铁', '有效锰', '有效铜', '有效锌']
+        # [key for key in checkDBData]
+    checkPHDataKey = ['阳离子交换量', '交换性盐基总量、交换性钾、交换性钠、交换性钙、交换性镁', '有效磷', '有效硫']
+        # [key for key in checkPHData]
+    # print('list',checkDBDataKey)
+    # print('list', checkPHDataKey)
+
+    checkDataRes = []
+    for index, row in data.iterrows():
+        str = ''
+        for item in row.index:
+            if row[item] == '未检测':
+                str = ''
+            elif row[item] == '未填写' or pd.isna(row[item]):
+                str += f"{item}未填写。"
+            elif not pd.isna(row[item]) and (item in checkDataKey) and (not pd.isna(checkData[item])): # 指标不为空 且 在通用指标列表中
+                if filter_special_characters(row[item]) != filter_special_characters(checkData[item]):
+                    str += f"{item}检测方法填报有误。"
+            elif (not pd.isna(row[item]) and (item in checkDBDataKey)):
+                if filter_special_characters(row[item]) != filter_special_characters(checkDBData[item][0]) and filter_special_characters(row[item]) != filter_special_characters(checkDBData[item][1]):
+                    str += f"{item}检测方法填报有误。"
+                # 指标在两种方法指标列表中
+            elif (not pd.isna(row[item]) and (item in checkPHDataKey)):
+                # 指标在区分ph值列表中
+                if item == '阳离子交换量' and row['pH'] <= 7.5:
+                    if filter_special_characters(row[item]) != filter_special_characters(checkPHData[item][0]):
+                        str += f"{item}检测方法填写有误。"
+                if item == '阳离子交换量' and row['pH'] > 7.5:
+                    if filter_special_characters(row[item]) != filter_special_characters(checkPHData[item][1]):
+                        str += f"{item}检测方法填写有误。"
+                if item == '交换性盐基总量、交换性钾、交换性钠、交换性钙、交换性镁' and row['pH'] <= 7.5:
+                    if filter_special_characters(row[item]) != filter_special_characters(checkPHData[item][0]):
+                        str += f"{item}检测方法填写有误。"
+                if item == '交换性盐基总量、交换性钾、交换性钠、交换性钙、交换性镁' and row['pH'] > 7.5:
+                    if filter_special_characters(row[item]) != filter_special_characters(checkPHData[item][0]):
+                        str += f"{item}检测方法填写有误。"
+                if item == '有效磷' and row['pH'] < 6.5:
+                    if filter_special_characters(row[item]) != filter_special_characters(checkPHData[item][0]):
+                        str += f"{item}检测方法填写有误。"
+                if item == '有效磷' and row['pH'] >= 6.5:
+                    if filter_special_characters(row[item]) != filter_special_characters(checkPHData[item][0]):
+                        str += f"{item}检测方法填写有误。"
+                if item == '有效硫' and row['pH'] < 7.5:
+                    if filter_special_characters(row[item]) != filter_special_characters(checkPHData[item][0]):
+                        str += f"{item}检测方法填写有误。"
+                if item == '有效硫' and row['pH'] >= 7.5:
+                    if filter_special_characters(row[item]) != filter_special_characters(checkPHData[item][0]):
+                        str += f"{item}检测方法填写有误。"
+        checkDataRes.append(str)
+    data['数据审核结果'] = checkDataRes
+    resData = data.style.apply(highlight_condition, axis=1)
+    # 数据写入表格
+    with pd.ExcelWriter(f'{url}/检测方法审核结果.xlsx', engine='openpyxl') as writer:
+        resData.to_excel(writer, index=False, sheet_name='检测方法审核')
+    return data[data['检测方法审核结果'] !='']
+
+
+# 8.数据填报审核
+def dataReportResult(data, url):
+    # 未检出项填报,空值填报,错误值处理
+    # 检测值有*号、/、未检测、空值、数值 为合理情况,
+    resData = []
+    for index, row in data.iterrows():
+        str = ''
+        for item in row.index:
+            if row[item] == '-' or row[item] == 0:
+                str = f"{item}数据填报错误。"
+        resData.append(str)
+    data['数据审核结果'] = resData
+    finData = data.style.apply(highlight_condition, axis=1)
+    # 数据写入表格
+    with pd.ExcelWriter(f'{url}/数据填报项审核结果.xlsx', engine='openpyxl') as writer:
+        finData.to_excel(writer, index=False, sheet_name='数据填报审核')
+
+
+# 9.土壤质地类型判断 这个之前已有,将土壤质地类型不一致的样本数据提取出来
+# 使用resData数据,判断土壤类型和土壤类型判断是否一致,不一致提取出不一致数据写入表格
+
+
+# 10.土壤检测数据超阈值样品统计表,将之前统计的超阈值的数据提取出来,显示原因
+# def getOverLineData(data, url):  # 所有阈值判断
+    # 提取数据项,异常原因,增加一列外业保持空值
+    # 提取每个表格审核结果不为空的数据,最后将所有数据合并
+    # resData =
+    # 数据写入表格
+    # with pd.ExcelWriter(f'{url}/超阈值样品统计表.xlsx', engine='openpyxl') as writer:
+    #     resData.to_excel(writer, index=False, sheet_name='超阈值数据')
+
+# 11.ph值统计 频度计算、历年数据统计、ph异常数据提取
+def getPHData(data, url):
+    resData = pd.DataFrame({})
+    # 计算频度
+    min_value = data['pH'].min()  # 最大值
+    max_value = data['pH'].max()  # 最小值
+    median_value = data['pH'].median()  # 中位数
+    mean_value = round(data['pH'].mean(),2) # 平均数
+    std_value = round(data['pH'].std(), 2)  # 标准差
+    resData['PH'] = [min_value, max_value, median_value, mean_value, std_value]
+    index_value = ['最小值', '最大值', '中位数', '平均数', '标准差']
+    resData.index = index_value
+    # 绘制分布图
+    x = np.arange(0, len(data['pH']), 1) # 横坐标数据
+    data = data.sort_values(by='pH', ascending=True)
+    y = data['pH']
+    getInteractiveImg(x, y, 'pH', [], [], '', [], [], '', url,
+                      'pH值分布图', '样品序号', 'pH', data['原样品编号'])
+
+    # 提取异常数据
+    abnormalData = pd.DataFrame({})
+    for index, row in data.iterrows():
+        if not pd.isna(row['pH']) and (row['pH'] < mean_value-3*std_value or row['pH'] > mean_value+3*std_value):
+            newRow = row[['原样品编号', '样品编号', '土地利用类型', 'pH']]
+            soilType = ''
+            if isinstance(row['土壤类型'], str):
+                if len(row['土壤类型'].split('_')) > 1:
+                    soilType = row['土壤类型'].split('_')[1]
+            newRow['土壤类型'] = soilType
+            newRow['外业情况'] = ''
+            abnormalData = abnormalData._append(newRow)
+    return {
+        '异常数据': abnormalData,
+        '频度分析': resData
+    }
+    # resData写进文档表格
+    # 异常数据写入表格
+    # 生成也可以写入文档表格
+    # with pd.ExcelWriter( './img/ph异常数据.xlsx', engine='openpyxl') as writer:
+    #     abnormalData.to_excel(writer, index=False, sheet_name='ph异常数据')
+    #     resData.to_excel(writer, sheet_name='频度分析')
+
+
+# 12.有机质和全氮 计算比值、绘制相关性图、提取异常数据形成表格
+def getNAndC(data, url):
+    # 去掉nan的值
+    data = data.dropna(subset=['有机质', '全氮'])
+    # 绘制散点图 拟合直线 计算方差
+    x = data['有机质']
+    y = data['全氮']
+    plt.scatter(x, y)
+    fig = go.Figure(data=go.Scatter(
+        x=x,
+        y=y,
+        text=data['原样品编号'].to_numpy(),
+        mode='markers', name='有机质与全氮',
+        marker=dict(
+            size=10,  # 点的大小
+            color='blue',  # 点的颜色
+        ))
+    )
+
+    # 使用sklearn的LinearRegression进行最小二乘法拟合
+    model = LinearRegression()
+    model.fit(x.to_numpy().reshape(-1, 1), y)
+    # 计算拟合直线的斜率和截距
+    slope = model.coef_[0]
+    intercept = model.intercept_
+    r, _ = np.corrcoef(y, slope * x + intercept)
+    # 绘制拟合直线
+    fig.add_trace(go.Scatter(x=x, y=slope * x + intercept,mode='lines', name='拟合直线'))
+    # plt.plot(x, slope * x + intercept, color='red', label='拟合直线',  linewidth=2)
+    # 设置图表布局
+    fig.update_layout(
+                      title={
+                          'text': f"有机质与全氮相关关系图,y={round(slope,2)}x + {round(intercept,2)},R²={round(r[1],2)}",
+                          'xanchor': 'center',  # 控制水平对齐,可选'left', 'center', 'right'
+                          'yanchor': 'bottom',  # 控制垂直对齐,可选'top', 'middle', 'bottom'
+                          'x': 0.5,  # 控制标题的水平位置,0.5代表中心,可以是小数(相对位置)或整数(像素位置)
+                          'y': 0.9  # 控制标题的垂直位置,0.9代表底部,可以是小数或整数
+                      },
+                      xaxis_title='有机质(g/kg)',
+                      yaxis_title='全氮(g/kg)')
+    html_file_path = f"{url}/有机质与全氮相关性分析图.html"
+    pio.write_html(fig, file=html_file_path, auto_open=False)
+    # 同时保存一份图片
+    pio.write_image(fig, f"{url}/有机质与全氮相关性分析图.png")
+    # plt.savefig('./img/审核报告图形/' + '有机质与全氮相关性分析图.png', dpi=500, bbox_inches='tight')
+    # plt.show()
+    abnormalData = pd.DataFrame({})
+    for index, row in data.iterrows():
+        if not pd.isna(row['有机质']) and not pd.isna(row['全氮']):
+            if row['有机质']/row['全氮'] <13 or row['有机质']/row['全氮'] > 20:
+                newRow = row[['原样品编号', '样品编号', '土地利用类型', '有机质', '全氮']]
+                soilType = ''
+                resStr = ''
+                if row['有机质']/row['全氮'] < 13:
+                    resStr = '偏低'
+                if row['有机质']/row['全氮'] > 20:
+                    resStr = '偏高'
+                if isinstance(row['土壤类型'], str):
+                    if len(row['土壤类型'].split('_')) > 1:
+                        soilType = row['土壤类型'].split('_')[1]
+                newRow['土壤类型'] = soilType
+                newRow['碳氮比'] = round(row['有机质']/row['全氮'], 2)
+                newRow['审核结果'] = resStr
+                newRow['外业情况'] = ''
+                abnormalData = abnormalData._append(newRow)
+    return abnormalData
+    # with pd.ExcelWriter('./img/碳氮比异常数据.xlsx', engine='openpyxl') as writer:
+    #     abnormalData.to_excel(writer, index=False, sheet_name='碳氮比异常数据')
+
+def getImg(x,y,label):
+    plt.scatter(x, y)
+    plt.xlabel('样品数量')
+    plt.ylabel(label)
+    # plt.savefig('./img/' + label + '数据分布图.png', dpi=500, bbox_inches='tight')
+    plt.show()
+
+
+# 13.全磷和有效磷,绘图,统计异常值,绘图绘制在同一个图中
+def getPData(data, url):
+    # 提取异常数
+    abnormalData = pd.DataFrame({})
+    # abnormalData.columns = ['原样品编号', '样品编号', '土地利用类型', '全磷', '有效磷', '土壤类型', '有效磷比', '外业情况']
+    for index, row in data.iterrows():
+        if not pd.isna(row['有效磷']) and not pd.isna(row['全磷']):
+            if row['有效磷'] /(1000 * row['全磷']) >= 0.15:
+                newRow = row[['原样品编号', '样品编号', '土地利用类型', '全磷', '有效磷']]
+                soilType = ''
+                if isinstance(row['土壤类型'], str):
+                    if len(row['土壤类型'].split('_')) > 1:
+                        soilType = row['土壤类型'].split('_')[1]
+                newRow['土壤类型'] = soilType
+                newRow['有效磷比'] = round(row['有效磷'] / (row['全磷']*10), 2)
+                newRow['外业情况'] = ''
+                abnormalData = abnormalData._append(newRow)
+
+    with pd.ExcelWriter(f'{url}/有效磷占全磷比异常数据.xlsx', engine='openpyxl') as writer:
+        abnormalData.to_excel(writer, index=False, sheet_name='有效磷占全磷比比异常数据')
+    if not data['全磷'].empty and not data['有效磷'].empty:
+        x1 = np.arange(0, len(data['全磷']), 1)
+        x2 = np.arange(0, len(data['有效磷']), 1)
+        x3 = np.arange(0, len(data['有效磷']/data['全磷']), 1)
+        data1 = data.sort_values(by='全磷', ascending=True)
+        data2 = data.sort_values(by='有效磷', ascending=True)
+        data['有效磷占比'] = data['有效磷']/10*data['全磷']
+        data3 = data.sort_values(by='有效磷占比', ascending=True)
+        y1 = data1['全磷']
+        y2 = data2['有效磷']
+        y3 = data3['有效磷占比']
+        # getImg(x1, y1,'全磷(g/kg)')
+        # getImg(x2, y2, '有效磷(mg/kg)')
+        # getImg(x3, y3, '有效磷占全磷比(%)')
+        getInteractiveImg(x1, y1,'全磷(g/kg)',[], [], '', [], [], '', url,
+                          '全磷分布图', '样品序号', '全磷(g/kg)', data1['原样品编号'])
+        getInteractiveImg(x2, y2, '有效磷(mg/kg)', [], [], '', [], [], '', url,
+                          '有效磷分布图', '样品序号', '有效磷(mg/kg)', data2['原样品编号'])
+        getInteractiveImg(x3, y3, '有效磷占全磷比(%)', [], [], '', [], [], '', url,
+                          '有效磷占全磷比分布图', '样品序号', '有效磷占全磷比(%)', data3['原样品编号'])
+        del data['有效磷占比']
+    return abnormalData
+
+
+
+# 14. 全钾、速效钾和缓效钾,绘图
+def getKData(data, url):
+    data = data.replace(np.nan,0)
+    x1 = np.arange(0, len(data['全钾']), 1)
+    y1 = data['全钾']
+    x2 = np.arange(0, len(data['速效钾'] + data['缓效钾']), 1)
+    y2 = data['速效钾']/1000 + data['缓效钾']/1000
+
+    getInteractiveImg(x1, y1, '全钾', x2, y2,'速效钾与缓效钾之和', [],[],'', url,'全钾与速效钾缓效钾之和关系统计图','样品序号','g/kg', data['原样品编号'])
+    x = np.arange(0, len(data['速效钾']), 1)
+    y = data['速效钾']
+    x_1 = np.arange(0, len(data['缓效钾']), 1)
+    y_1 = data['缓效钾']
+    getInteractiveImg(x, y, '速效钾', x_1, y_1, '缓效钾', [], [], '', url,
+                      '速效钾与缓效钾关系统计图', '样品序号', 'mg/kg', data['原样品编号'])
+
+
+# 15.重金属 已有 提取重金属异常数据即可
+def getMetal(simpleData):
+    # resData_14 数据中提取重金属超标的数据,提取相应的指标形成表格
+    resData = ''
+    return resData
+# 16.阳离子交换量与交换性盐基总量
+def cationExchangeCapacity(data, url):
+    # 绘图
+    x = data['阳离子交换量']
+    y = data['交换性盐基总量']
+    getInteractiveImg(x, y, '阳离子交换量与交换性盐基总量相关关系', [], [], '', [], [], '', url,
+                      '阳离子交换量与交换性盐基总量相关关系', '样品序号', 'mg/kg', data['原样品编号'])
+
+# cationExchangeCapacity('')
+# 17.交换性盐基:二者之差 交换性盐基总量cmol(+)/kg 交换性钙镁钠钾之和 区分ph>7.5 和ph值<7.5
+def changeCation(data,url):
+    hightData = data[data['pH'] > 7.5]
+    lowData = data[data['pH'] <= 7.5]
+    hightData = hightData.apply(pd.to_numeric, errors="coerce")
+    lowData = lowData.apply(pd.to_numeric, errors="coerce")
+    x_h = np.arange(0, len(hightData['交换性盐基总量']), 1)
+
+    y_h = hightData['交换性盐基总量']
+    y1_h = (hightData['交换性钙'] + hightData['交换性镁'] + hightData['交换性钾'] + hightData['交换性钠'])
+    y2_h = (y_h-y1_h)
+    # 绘图
+    getInteractiveImg(x_h, y_h, '交换性盐基总量', x_h, y1_h, '钙镁钾钠之和', x_h, y2_h, '交换性盐基总量与钙镁钾钠和之差', url,
+                      '交换性盐基总量与交换性盐相关关系(pH大于7.5)', '样品序号', 'cmol/kg', hightData['原样品编号'])
+
+    x_l = np.arange(0, len(lowData['交换性盐基总量']), 1)
+    y_l = lowData['交换性盐基总量']
+    y1_l = (lowData['交换性钙'] + lowData['交换性镁'] + lowData['交换性钾'] + lowData['交换性钠'])
+    y2_l = (y_l - y1_l)
+
+    getInteractiveImg(x_l, y_l, '交换性盐基总量', x_l, y1_l, '钙镁钾钠之和', x_l, y2_l,
+                      '交换性盐基总量与钙镁钾钠和之差', url,
+                      '交换性盐基总量与交换性盐相关关系(pH小于等于7.5)', '样品序号', 'cmol/kg', lowData['原样品编号'])
+
+# 18.水溶性盐总量、电导率、离子总量全盐量分布图,全盐量和电导率相关性分析,水溶性盐与离子总量关系
+def manyTypes(data,url):
+    # data = data.replace('未检测', np.nan)
+    data = data.dropna(subset=['全盐量', '电导率'])
+
+    print(3.41)
+    # 全盐量分布图
+    x = np.arange(0, len(data['全盐量']), 1)
+    data_1 = data.sort_values(by='全盐量', ascending=True)
+    y = data_1['全盐量']
+    getInteractiveImg(x, y, '全盐量', [], [], '', [], [],
+                      '', url,
+                      '全盐量分布图', '样品序号', '全盐量(g/kg)', data_1['原样品编号'])
+    # 电导率分布图
+    # x1 = np.arange(0, len(data['电导率']), 1)
+    # y1 = data['电导率'].sort_values()
+    # getInteractiveImg(x1, y1, '电导率', [], [], '', [], [],
+    #                   '', './img/审核报告图形',
+    #                   '电导率分布图', '样品序号', '电导率(mS/cm)', data['原样品编号'], 'fileUrl',
+    #                   'loc')
+    print(3.42)
+    x1 = data['全盐量'].dropna()
+    y1 = data['电导率'].dropna()
+    print('电导率', y1)
+    # plt.scatter(x, y)
+    fig = go.Figure(data=go.Scatter(
+        x=x1,
+        y=y1,
+        text=data['原样品编号'].to_numpy(),
+        mode='markers', name='全盐量与电导率相关关系',
+        marker=dict(
+            size=10,  # 点的大小
+            color='blue',  # 点的颜色
+        ))
+    )
+    print(3.43)
+    # 使用sklearn的LinearRegression进行最小二乘法拟合
+    model = LinearRegression()
+    model.fit(x1.to_numpy().reshape(-1, 1), y1)
+    # 计算拟合直线的斜率和截距
+    slope = model.coef_[0]
+    intercept = model.intercept_
+    r, _ = np.corrcoef(y1, slope * x1 + intercept)
+    # 绘制拟合直线
+    fig.add_trace(go.Scatter(x=x1, y=slope * x1 + intercept, mode='lines', name='拟合直线'))
+    # plt.plot(x, slope * x + intercept, color='red', label='拟合直线',  linewidth=2)
+    # 设置图表布局
+    fig.update_layout(
+                      title={
+                          'text':f"全盐量与电导率相关关系图,y={round(slope, 2)}x + {round(intercept, 2)},R²={round(r[1], 2)}",
+                          'xanchor': 'center',  # 控制水平对齐,可选'left', 'center', 'right'
+                          'yanchor': 'bottom',  # 控制垂直对齐,可选'top', 'middle', 'bottom'
+                          'x': 0.5,  # 控制标题的水平位置,0.5代表中心,可以是小数(相对位置)或整数(像素位置)
+                          'y': 0.9  # 控制标题的垂直位置,0.9代表底部,可以是小数或整数
+                      },
+                      xaxis_title='全盐量(g/kg)',
+                      yaxis_title='电导率(mS/cm)')
+    html_file_path = f"{url}/全盐量与电导率相关性分析图.html"
+    pio.write_html(fig, file=html_file_path, auto_open=False)
+    # 同时保存一份图片
+    pio.write_image(fig, f"{url}/全盐量与电导率相关性分析图.png")
+    print(3.44)
+
+
+    # 离子总量 水溶性盐总量及差值
+    filterData = data.dropna(subset=['全盐量', '离子总量'])
+    x2 = np.arange(0, len(filterData['离子总量']), 1)
+    print(x2)
+    print(3.441)
+    print(filterData['离子总量'])
+    y2 = filterData['离子总量']
+    print(y2)
+    print(3.442)
+    y3 = filterData['全盐量']
+    print(y3)
+    print(3.443)
+
+    y4 = (y2-y3)
+
+    getInteractiveImg(x2, y2, '离子总量', x2, y3, '水溶性盐总量', x2, y4,
+                      '离子总量与水溶性盐总量之差', url,
+                      '离子总量与水溶性盐总量关系图', '样品数量', '离子总量/水溶性盐总量(g/kg)', data['原样品编号'])
+
+
+
+

+ 1817 - 0
rongzhong.py

@@ -0,0 +1,1817 @@
+import pandas as pd
+import numpy as np
+import time
+import public as pb
+import openpyxl
+import matplotlib.pyplot as plt
+from scipy.stats import spearmanr
+# import tkinter as tk
+# from tkinter import ttk
+from tkinter import filedialog
+from tkinter import messagebox
+from openpyxl import load_workbook
+from openpyxl.drawing.image import Image as OImage
+import os
+import ttkbootstrap as ttk
+from ttkbootstrap.constants import *
+from PIL import Image, ImageTk
+from ttkbootstrap.dialogs import Messagebox
+import plotly.graph_objects as go
+import plotly.io as pio
+from sklearn.linear_model import LinearRegression
+import report
+import partReport
+from docx import Document
+from openpyxl.worksheet.hyperlink import Hyperlink
+import docx
+from docx import Document
+from docx.shared import Inches
+from docx.oxml import OxmlElement, ns
+from docx.shared import Pt, RGBColor
+from docx.oxml.ns import nsdecls, nsmap
+from docx.oxml import parse_xml
+from docx.enum.dml import MSO_THEME_COLOR_INDEX
+from docx import Document
+from docx.opc.constants import RELATIONSHIP_TYPE as RT
+from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT
+from docx.oxml.ns import qn
+from docx.enum.text import WD_ALIGN_PARAGRAPH
+from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
+import uuid
+import hashlib
+from ttkbootstrap.dialogs import Querybox
+# 显示所有数据
+pd.set_option('display.width', 10000) # 设置字符显示宽度
+pd.set_option('display.max_rows', None) # 设置显示最大行
+pd.set_option('display.max_columns', None) # 设置显示最大列,None为显示所有列
+# 一些全局变量
+changeFileUrl = '' # 选择的文件路径
+saveFileUrl = '' #保存文件路径
+resData_1_Style = None
+resData_2 = None
+resData_3_Style = pd.DataFrame({})
+resData_4 = pd.DataFrame({})
+resData_5_Style = None
+resData_6 = None
+resData_8_Style = None
+resData_7 = None
+resData_10_Style = None
+resData_9 = None
+resData_12_Style = None
+resData_11 = None
+resData_14_Style = None
+resData_13 = None
+htmlContent = []
+htmlStatisticsContent = []
+# 报告需要用到的数据
+table_1_data = pd.DataFrame({})
+table_3_data = pd.DataFrame({})
+table_5_data = pd.DataFrame({})
+table_8_data = pd.DataFrame({}) # 样品编号替换为编号
+table_10_data = pd.DataFrame({})
+table_12_data = pd.DataFrame({})
+table_14_data = pd.DataFrame({})
+checkType = '' # 保存可用类型
+# 保存需要用到的异常指标数据
+table_1_index = pd.DataFrame({})
+table_3_index = pd.DataFrame({})
+table_5_index = pd.DataFrame({})
+table_8_index = pd.DataFrame({}) # 样品编号替换为编号
+table_10_index = pd.DataFrame({})
+table_12_index = pd.DataFrame({})
+table_14_index = pd.DataFrame({})
+# 合并数据 检查审核结果中有阈值以外字段的 提取出来 todo 提取序号 编号 土地类型
+# 设置字体
+# 设置字体 微软雅黑 新罗马 加粗
+plt.rcParams['font.family'] = ['Times New Roman','Microsoft YaHei']
+# 设置字体加粗
+font = {'weight': 'bold'}
+plt.rc('font', **font)  # 应用字体设置
+# 公共函数
+def calculate_row_range(row):
+
+    return row.max() - row.min()  # 对每一行计算最大值与最小值之差
+
+# 转数字
+def filter_number(arr):
+    """
+    :param arr:
+    :return:
+    """
+    return pd.to_numeric(arr, errors='coerce')
+# 公共函数处理重复样品:根据样品编号筛选出所有重复的样品数据,求均值后再和总数据合并
+def getRepeat(arr):
+    df1 = arr[arr.duplicated(subset='原样品编号',keep=False)].drop_duplicates('原样品编号')['原样品编号']
+    dpData = pd.DataFrame({})
+    # 循环 筛选对应重复数据
+    for i in df1:
+        dpArr = arr[arr['原样品编号'] == i]
+        numeric_cols = dpArr.select_dtypes(include=['int', 'float']).columns
+        dpArr[numeric_cols] = dpArr[numeric_cols].apply(lambda x: round(x.mean(),2), axis=0)
+        newData = dpArr.drop_duplicates(subset=['原样品编号'], keep='last')
+        dpData = dpData._append(newData)
+    return dpData
+# 存疑行标红
+def highlight_condition(s):
+    if s['审核结果'] != '' and not pd.isna(s['审核结果']):
+        return ['background-color: #99CC99']*len(s)
+    else:
+        return ['']*len(s)
+
+# 自适应列宽
+def autoColumns(url):
+    wb = load_workbook(url)
+    ws = wb.active
+    ws_pd = wb['频度分析']
+    # 自适应调整列宽
+    for column_cells in ws.columns:
+        length = max(len(str(cell.value)) for cell in column_cells if cell.value is not None)
+        ws.column_dimensions[column_cells[0].column_letter].width = length + 15  # 可以根据需要调整额外的宽度
+    for column_cells in ws_pd.columns:
+        length = max(len(str(cell.value)) for cell in column_cells if cell.value is not None)
+        ws_pd.column_dimensions[column_cells[0].column_letter].width = length + 5  # 可以根据需要调整额外的宽度
+    # 保存调整后的Excel文件
+    wb.save(url)
+
+
+# 频度分析函数 公用
+def frequency_analysis(arr):
+    qua_2 = arr.quantile(0.02)
+    print(1.55)
+    qua_5 = arr.quantile(0.05)
+    qua_10 = arr.quantile(0.1)
+    qua_20 = arr.quantile(0.2)
+    qua_50 = arr.quantile(0.5)
+    qua_80 = arr.quantile(0.8)
+    qua_90 = arr.quantile(0.9)
+    qua_95 = arr.quantile(0.95)
+    qua_98 = arr.quantile(0.98)
+    min_value = arr.min()
+    max_value = arr.max()
+    print(1.6)
+    median_value = arr.median()  # 中位数
+    jc_value = arr.max() - arr.min()  # 极差
+    print(1.7)
+    std_value = arr.std()  # 标准差
+    mean_value = arr.mean()  # 平均数
+    variation_value = std_value / mean_value  # 变异系数 = 标准差/均值
+    data = pd.DataFrame(
+        [qua_2, qua_5, qua_10, qua_20, qua_50, qua_80, qua_90, qua_95, qua_98, min_value, max_value, median_value,
+         jc_value, std_value, mean_value, variation_value])
+    index_value = ['2%', '5%', '10%', '20%', '50%', '80%', '90%', '95%', '98%', '最小值', '最大值', '中位数', '极差',
+                   '标准差', '平均数', '变异系数']
+    # 汇总数据
+    data.index = index_value
+    data_res = round(data, 2)
+    print('data_res', data_res)
+    return data_res
+
+# 绘图函数
+def getImg(x,y,url,name,sheetName,xLabel,YLabel,numArr,fileUrl,loc):
+    coef, p_value = spearmanr(x, y)
+    fig = go.Figure(data=go.Scatter(
+        x=x,
+        y=y,
+        text=numArr.to_numpy(),
+        mode='markers',name='散点数据'))
+    # 设置图表布局
+    fig.update_layout(title=f"{xLabel}和{YLabel}Spearman相关性系数: {coef:.2f}",
+                      xaxis_title=xLabel,
+                      yaxis_title=YLabel)
+
+    model = LinearRegression()
+    model.fit(x.to_numpy().reshape(-1, 1), y)  # 用x的平方作为特征值
+    y_pred = model.predict(x.to_numpy().reshape(-1, 1))
+    fig.add_trace(go.Scatter(x=x, y=y_pred, mode='lines', name='拟合直线'))
+
+    html_file_path = f"{url}/{name}频度统计图.html"
+    pio.write_html(fig, file=html_file_path, auto_open=False)
+    # 在表格中插入html
+    workbook = load_workbook(filename=fileUrl)
+    # 选择一个工作表
+    ws = workbook[sheetName]
+    # 将 HTML 内容作为富文本写入单元格
+    ws[loc] = '=HYPERLINK("file:///{0}","点击查看统计图")'.format(html_file_path)
+    workbook.save(fileUrl)
+
+
+# 频度统计直方图
+def getStatisticsImg(data,xLabel,name,fileUrl,url,loc):
+    fig = go.Figure(data=[go.Histogram(x=data)])
+    # 设置标题和其他格式
+    fig.update_layout(
+        title_text= f"{name}统计图",
+        xaxis_title=xLabel,
+        yaxis_title='频次',
+        bargap=0.2,  # 相邻位置坐标的钢筋之间的间隙
+        bargroupgap=0.1  #
+    )
+    html_file_path = f"{url}/{name}频度统计图.html"
+    pio.write_html(fig, file=html_file_path, auto_open=False)
+    # 在表格中插入html
+    workbook = load_workbook(filename=fileUrl)
+    # 选择一个工作表
+    ws = workbook['频度分析']
+    # 将 HTML 内容作为富文本写入单元格
+    ws[loc] = '=HYPERLINK("file:///{0}","点击查看统计图")'.format(html_file_path)
+    workbook.save(fileUrl)
+
+# ---------------数据读取计算-----------------
+def is_trial_file():
+    try:
+        with open('./html/config.txt', 'r') as file:
+            start_date_str = file.read()
+        return True
+    except FileNotFoundError:
+        # 如果文件不存在,这是用户第一次打开,开始试用
+        with open('./html/config.txt', 'w') as file:
+            file.write('376d8bf8f8855ad8de997fa5dac1bd24956aef0cbfa0cf8ac04053a7043e3d90248051f6f03f02b20430949504a5556fb112131fc81205768229ffa023831b04')
+        return False
+
+def is_code_file():
+    try:
+        with open('./html/code.txt', 'r') as file:
+            start_date_str = file.read()
+        return True
+    except FileNotFoundError:
+        # 如果文件不存在,这是用户第一次打开,开始试用
+
+        return False
+
+
+def getOption():
+    # 检查标记文件和注册码文件
+    type = 'HUNDRED_DATA' # 试用100条
+    configFile = './html/config.docx'
+    codeFile = './html/code.docx'
+    # resginNum = getNum()
+    # 注册码正确 可用
+    if not is_trial_file() and not is_code_file():
+        type = 'HUNDRED_DATA'
+    elif is_trial_file() and not is_code_file():
+        type = 'OVER_LINE'
+    elif is_code_file():
+        type = 'ALL'
+    return type
+
+
+def getNum():
+    device_id = uuid.getnode()  # 获取设备的唯一ID,通常是MAC地址
+    str = f'{device_id}-window-pc-user'
+    sha256 = hashlib.sha256()
+    sha256.update(str.encode('utf-8'))  # 将字符串编码为UTF-8格式
+    newStr = sha256.hexdigest()
+    front_8 = newStr[:8]
+    middle_40_36 = newStr[36:40]
+    end_4 = newStr[-4:]
+    return f"{front_8}{middle_40_36}{end_4}"
+# 总体审核函数
+def checkData(fileUrl):
+    try:
+        # 这里先弹窗提示输入注册码,获取注册码请点击下方获取申请码按钮了解详情。
+        # 无注册码点击确定按钮弹框消失,但此时只能使用一百条数据
+        # 默认读取第一个sheet
+
+        type = getOption()
+        global checkType
+        checkType = type
+        data = pd.read_excel(fileUrl,converters={'原样品编号': str})
+        print('fileUrl', data['总砷'])
+        if type == 'OVER_LINE':
+            show_error('试用已结束,使用更多请点击下方获取申请码按钮联系管理员!')
+        elif type == 'HUNDRED_DATA' or type == 'ALL':
+            if type == 'HUNDRED_DATA':
+                data = data.head(100)
+            global htmlContent
+            htmlContent = []
+            if not data.empty:
+                # 开始审核
+                # 计算均值--已有
+                # 极差 极差的具体计算公式为:‌R=xmax−xmin
+                # 删除质控样品 编号里含zk的样品可以删除
+                simpleData = data.dropna(subset=['原样品编号'])
+
+                simpleData = simpleData[~simpleData['原样品编号'].str.contains('ZK')]
+                simpleData = simpleData.replace(r'[^.\w]+', '', regex=True)
+                # print('simpleData',simpleData)
+                simpleData = simpleData.replace('未检测', np.nan)
+                simpleData.iloc[:, 3:] = simpleData.iloc[:, 3:].apply(pd.to_numeric,errors='ignore')
+                print('simpleData--砷', simpleData['总镉'].min(), simpleData['总镉'].max())
+                strList = ['原样品编号','样品编号','地理位置','土壤类型','母质','土地利用类型','土壤质地']
+                for i in simpleData.columns:
+                    if i not in strList:
+                        simpleData[i] = pd.to_numeric(simpleData[i], errors='ignore')
+                # 处理重复样品
+                res = getRepeat(simpleData)
+                simpleData = simpleData._append(res).drop_duplicates(subset=['原样品编号'], keep='last')
+                print('simpleData--砷',simpleData['总砷'].min() )
+                jCData = simpleData[['土壤容重1(g/cm³)', '土壤容重2(g/cm³)', '土壤容重3(g/cm³)', '土壤容重4(g/cm³)']]
+                # 计算土壤容重均值
+                rZMean = round(simpleData[['土壤容重1(g/cm³)', '土壤容重2(g/cm³)', '土壤容重3(g/cm³)', '土壤容重4(g/cm³)']].mean(
+                    axis=1),2)
+                # 极差值
+                jCResData = jCData.apply(calculate_row_range, axis=1)  # 在每一行上应用函数,‌axis=1表示按行操作
+                # 相对极差 相对极差(‌%)‌= 极差(‌绝对极差)‌/ 数值平均值 × 100%。‌
+                relativeJCData = jCResData / simpleData['土壤容重平均值(g/cm³)'] * 100
+                # 加和
+                plusData = simpleData['2~0.2mm颗粒含量'] + simpleData['0.2~0.02mm颗粒含量'] + simpleData[
+                    '0.02~0.002mm颗粒含量'] + simpleData['0.002mm以下颗粒含量']
+                # ---------------表1----------数据汇总
+                resData = pd.DataFrame({
+                    '编号': simpleData['原样品编号'],
+                    '地理位置': simpleData['地理位置'],
+                    '土壤类型': simpleData['土壤类型'],
+                    '土地利用类型': simpleData['土地利用类型'],
+                    '母质': simpleData['母质'],
+                    '土壤质地': simpleData['土壤质地'],
+                    '土壤容重1(g/cm3)': simpleData['土壤容重1(g/cm³)'],
+                    '土壤容重2(g/cm3)': simpleData['土壤容重2(g/cm³)'],
+                    '土壤容重3(g/cm3)': simpleData['土壤容重3(g/cm³)'],
+                    '土壤容重4(g/cm3)': simpleData['土壤容重4(g/cm³)'],
+                    '土壤容重平均值(g/cm3)': simpleData['土壤容重平均值(g/cm³)'],
+                    '土壤容重平均值(g/cm3)(计算)': rZMean,
+                    '极差': jCResData,
+                    '相对极差(%)': relativeJCData,
+                    '洗失量(吸管法需填)%': simpleData['洗失量(吸管法需填)'],
+                    '2-0.2mm颗粒含量%': simpleData['2~0.2mm颗粒含量'],
+                    '0.2-0.02mm颗粒含量%': simpleData['0.2~0.02mm颗粒含量'],
+                    '0.02-0.002mm颗粒含量%': simpleData['0.02~0.002mm颗粒含量'],
+                    '0.002mm以下颗粒含量%': simpleData['0.002mm以下颗粒含量'],
+                    '加和%': plusData,
+                    'pH': simpleData['pH']
+                })
+                # 调用审核函数 得到审核结果
+                table_1_res = pb.soil_bulk_density(resData)
+                resData = resData.reset_index(drop=True)
+                resData['审核结果'] = table_1_res['审核结果']
+                global table_1_data
+                table_1_data_res = resData[resData['土壤质地'] != resData['土壤类型(判断)']]
+                table_1_data = resData
+                # 提取异常指标数据
+                global table_1_index
+                table_1_index = pd.DataFrame({
+                    '样品编号': simpleData['样品编号'],
+                    '土地利用类型': resData['土地利用类型'],
+                    '指标': table_1_res['异常指标'],
+                    '原因': table_1_res['审核结果']
+                })
+                # 这里数据直接使用即可(土壤质地填报)todo
+                del resData['土壤类型(判断)']
+                resData.insert(loc=6, column='土壤类型(判断)', value=table_1_res['土壤类型(判断)'])
+                global resData_1_Style
+                resData_1_Style = resData.style.apply(highlight_condition,axis=1)
+                # 表2--------------------------表2 土壤容重与机械组成总体数据频度分析----------------------------------------
+                # 计算6个指标的百分位 及其他值 2% 5% 10% 20% 50% 80% 90% 95% 98% 最小值 最大值 中位数 极差 标准差 平均数 变异系数
+                # 土壤容重均值 rZMean
+                data_2 = pd.DataFrame({
+                    '土壤容重(g/cm3)': resData['土壤容重平均值(g/cm3)(计算)'],
+                    '洗失量(吸管法需填)%': simpleData['洗失量(吸管法需填)'],
+                    '2-0.2mm颗粒含量%': simpleData['2~0.2mm颗粒含量'],
+                    '0.2-0.02mm颗粒含量%': simpleData['0.2~0.02mm颗粒含量'],
+                    '0.002-0.002mm颗粒含量%': simpleData['0.02~0.002mm颗粒含量'],
+                    '0.002mm以下颗粒含量%': simpleData['0.002mm以下颗粒含量']
+                })
+                global resData_2
+                print(1.5)
+                resData_2 = frequency_analysis(data_2)
+                print(2)
+                # 表3--------------------------表3水稳性大团聚体数据汇总----------------------------------------
+                # 数据计算 这里数据暂时还没有 数据获取到以后再进行测试
+                resData_3 = pd.DataFrame({
+                    '编号': simpleData['原样品编号'],
+                    '总和(%)': simpleData['水稳性大团聚体总和(%)'],
+                    '>5mm%': simpleData['水稳>5mm(%)'],
+                    '3-5mm%': simpleData['水稳3mm~5mm(%)'],
+                    '2-3mm%': simpleData['水稳2mm~3mm(%)'],
+                    '1-2mm%': simpleData['水稳1mm~2mm(%)'],
+                    '0.5-1mm%': simpleData['水稳0.5mm~1mm(%)'],
+                    '0.25-0.5mm%': simpleData['水稳0.25mm~0.5mm(%)'],
+                    'pH值': simpleData['pH'],
+                    '有机质g/kg': simpleData['有机质'],
+                    '土地利用类型': simpleData['土地利用类型'],
+                    '母质': simpleData['母质']
+                })
+                # 数据审核
+                resData_3 = resData_3.reset_index(drop=True)
+                res_3_v = pb.water_stable(resData_3)
+                resData_3['审核结果'] = res_3_v['审核结果']
+                global resData_3_Style
+                global table_3_data
+                table_3_data = resData_3
+                # 提取异常数据
+                global table_3_index
+                table_3_index = pd.DataFrame({
+                    '样品编号': simpleData['样品编号'],
+                    '指标': res_3_v['异常指标'],
+                    '原因': res_3_v['审核结果']
+                })
+                resData_3_Style = resData_3.style.apply(highlight_condition, axis=1)
+                # 表4--------------------------表4 水稳性大团聚体频度分析-----------------------
+                print(3)
+                resData_4_need = resData_3[['总和(%)','>5mm%','3-5mm%','2-3mm%','1-2mm%','0.5-1mm%','0.25-0.5mm%']]
+                global resData_4
+                resData_4 = frequency_analysis(resData_4_need)
+                print(3.1)
+                # 表5--------------------------表5pH、阳离子交换量、交换性盐基基础数据收集----------------------------------------
+                forPlus = simpleData['交换性钙'] + simpleData['交换性镁'] + simpleData['交换性钾'] + simpleData['交换性钠']
+                resData_5 = pd.DataFrame({
+                    '编号': simpleData['原样品编号'],
+                    'pH': simpleData['pH'],
+                    '含水量': simpleData['风干试样含水量(分析基)'],
+                    '土壤类型': simpleData['土壤类型'],
+                    '阳离子交换量Cmol(+)/kg': simpleData['阳离子交换量'],
+                    '交换性盐总量Cmol(+)/kg': simpleData['交换性盐基总量'],
+                    '交换性钙Cmol(1/2Ca2+)/kg': simpleData['交换性钙'],
+                    '交换性镁cmol(1/2Mg2+)/kg': simpleData['交换性镁'],
+                    '交换性钾Cmol(+)/kg': simpleData['交换性钾'],
+                    '交换性钠cmol(+)/kg': simpleData['交换性钠'],
+                    '四大离子之和': forPlus,
+                    '阳交量与交盐量差': simpleData['阳离子交换量'] - simpleData['交换性盐基总量'],
+                    '盐基饱和度%': simpleData['交换性盐基总量'] / simpleData['阳离子交换量']  # 交换性盐基/阳离子交换量
+                })
+                print(3.2)
+                resData_5 = resData_5.reset_index(drop=True)
+                res_5_v = pb.cation_value(resData_5)
+                print(3.3)
+                print('res_5_v', res_5_v)
+                resData_5['审核结果'] = res_5_v['审核结果']
+                global resData_5_Style
+                global table_5_data
+                table_5_data = resData_5
+                # 提取异常数据
+                print(3.5)
+                global table_5_index
+                table_5_index = pd.DataFrame({
+                    '样品编号': simpleData['样品编号'],
+                    '指标': res_5_v['异常指标'],
+                    '原因': res_5_v['审核结果']
+                })
+                resData_5_Style = resData_5.style.apply(highlight_condition, axis=1)
+                print(4)
+                # 表6--------------------------表6----------------------------------------
+                global resData_6
+                resData_6 = frequency_analysis(resData_5[['pH']])
+
+                # 表8--------------------------表8----------------------------------------
+                # 离子可能存在未检测情况 对离子指标进行转数字操作 防止后续计算出错
+                naArr = filter_number(simpleData['水溶性Na⁺含量'])
+                kArr = filter_number(simpleData['水溶性K⁺含量'])
+                caArr = filter_number(simpleData['水溶性Ca²⁺含量'])
+                mgArr = filter_number(simpleData['水溶性Mg²⁺含量'])
+                clArr = filter_number(simpleData['水溶性Cl⁻含量'])
+                coArr = filter_number(simpleData['水溶性CO₃²⁻含量'])
+                hcoArr = filter_number(simpleData['水溶性HCO₃⁻含量'])
+                soArr = filter_number(simpleData['水溶性SO₄²⁻含量'])
+
+                # 数据转换
+                changeNa = naArr * 23 / 100
+                changK = kArr * 39 / 100
+                changeCa = caArr * 40 / 100
+                changeMg = mgArr * 24 / 100
+                changeCl = clArr * 35 / 100
+                changeCo = coArr * 60 / 100
+                changeCOH = hcoArr * 61 / 100
+                changeSo = soArr * 96 / 100
+                eightPlusArr = changeNa + changK + changeCa + changeMg + changeCl + changeCo + changeCOH + changeSo
+                totalCations = changeNa + changK + changeCa + changeMg
+                totalAnions = changeCl + changeCo + changeCOH + changeSo
+                allArr = filter_number(simpleData['全盐量'])  # 单位g/kg
+                resData_8 = pd.DataFrame({
+                    '样品编号': simpleData['原样品编号'],
+                    'pH': simpleData['pH'],
+                    '水溶性全盐量g/kg': allArr,
+                    '电导率ms/cm': simpleData['电导率'],
+                    '水溶性钠离子含量Cmol(Na+)/kg': naArr,
+                    '水溶性钾离子含量Cmol(K+)/kg': kArr,
+                    '水溶性钙离子含量cmol(1/2Ca2+)/kg': caArr,
+                    '水溶性镁离子Cmol(1/2Mg2+)/kg': mgArr,
+                    '水溶性氯离子含量cmol(Cl-)/kg': clArr,
+                    '水溶性碳酸根离子含量cmol(1/2CO32+)/kg': coArr,
+                    '水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg': hcoArr,
+                    '水溶性硫酸根离子含量cmol(1/2SO42-)/kg': soArr,
+                    '八大离子加和g/kg': eightPlusArr,
+                    '(水溶性全盐量-八大离子加和)/水溶性全盐量×100': (allArr - eightPlusArr) / allArr * 100,
+                    '离子总量g/kg': filter_number(simpleData['离子总量']),
+                    '阳离子总量-阴离子总量': totalCations - totalAnions,
+                    '土地利用类型': simpleData['土地利用类型']
+                })
+                # 调用判断函数
+                res_value_8 = pb.eight_ion_coun(resData_8, simpleData)
+                resData_8 = resData_8.reset_index(drop=True)
+                resData_8['审核结果'] = res_value_8['审核结果']
+                global resData_8_Style
+                global table_8_data
+                table_8_data = resData_8
+                # 提取异常数据
+                global table_8_index
+                table_8_index = pd.DataFrame({
+                    '样品编号': simpleData['样品编号'],
+                    '指标': res_value_8['异常指标'],
+                    '原因': res_value_8['审核结果']
+                })
+                resData_8_Style = resData_8.style.apply(highlight_condition, axis=1)
+                print(5)
+                # 表7--------------------------表7 数据频度分析----------------------------------------
+                global resData_7
+                resData_7 = frequency_analysis(resData_8[['水溶性全盐量g/kg', '电导率ms/cm']])
+
+                # 表10--------------------------表10 有机质、全氮、全磷、全钾数据------------------------
+                resData_10 = pd.DataFrame({
+                    '编号': simpleData['原样品编号'],
+                    '有机质g/kg': simpleData['有机质'],
+                    '全氮g/kg': simpleData['全氮'],
+                    '全磷g/kg': simpleData['全磷'],
+                    '有效磷g/kg': simpleData['有效磷'],
+                    '全钾g/kg': simpleData['全钾'],
+                    '缓效钾mg/kg': simpleData['缓效钾'],
+                    '速效钾mg/kg': simpleData['速效钾'],
+                    'pH': simpleData['pH'],
+                    '母质': simpleData['母质'],
+                    '土地利用类型': simpleData['土地利用类型'],
+                    '交换性钾': simpleData['交换性钾'],
+                    '阳离子交换量': simpleData['阳离子交换量']
+                })
+                # 调用判断函数
+                res_value_10 = pb.nutrient_data(resData_10)
+                resData_10 = resData_10.reset_index(drop=True)
+                resData_10['审核结果'] = res_value_10['审核结果']
+                print(6)
+                # 写入表格
+                global resData_10_Style
+                global table_10_data
+                table_10_data = resData_10
+                # 提取异常数据
+                global table_10_index
+                table_10_index = pd.DataFrame({
+                    '样品编号': simpleData['样品编号'],
+                    '指标': res_value_10['异常指标'],
+                    '原因': res_value_10['审核结果']
+                })
+                resData_10_Style = resData_10.style.apply(highlight_condition, axis=1)
+                # 表9--------------------------表9----------------------------------------
+                # 计算频度数据
+                global resData_9
+                resData_9 = frequency_analysis(resData_10[
+                                                      ['有机质g/kg', '全氮g/kg', '全磷g/kg', '有效磷g/kg', '全钾g/kg',
+                                                       '缓效钾mg/kg', '速效钾mg/kg']])
+                # 表12--------------------------表12 土壤指标含量----------------------------------------
+                resData_12 = pd.DataFrame({
+                    '编号': simpleData['原样品编号'],
+                    'pH': simpleData['pH'],
+                    '母质': simpleData['母质'],
+                    '有机质': simpleData['有机质'],
+                    '全氮': simpleData['全氮'],
+                    '全磷': simpleData['全磷'],
+                    '全钾': simpleData['全钾'],
+                    '有效磷': simpleData['有效磷'],
+                    '速效钾': simpleData['速效钾'],
+                    '缓效钾': simpleData['缓效钾'],
+                    '有效硫mg/kg': simpleData['有效硫'],
+                    '有效硅mg/kg': simpleData['有效硅'],
+                    '有效铁mg/kg': simpleData['有效铁'],
+                    '有效锰mg/kg': simpleData['有效锰'],
+                    '有效铜mg/kg': simpleData['有效铜'],
+                    '有效锌mg/kg': simpleData['有效锌'],
+                    '有效硼mg/kg': simpleData['有效硼'],
+                    '有效钼mg/kg': simpleData['有效钼']
+                })
+
+                # 调用判断函数
+                res_value_12 = pb.soil_metal(resData_12)
+                resData_12 = resData_12.reset_index(drop=True)
+                resData_12['审核结果'] = res_value_12['审核结果']
+                global resData_12_Style
+                global table_12_data
+                table_12_data = resData_12
+                # 提取异常数据
+                global table_12_index
+                table_12_index = pd.DataFrame({
+                    '样品编号': simpleData['样品编号'],
+                    '指标': res_value_12['异常指标'],
+                    '原因': res_value_12['审核结果']
+                })
+                resData_12_Style = resData_12.style.apply(highlight_condition, axis=1)
+                print(7)
+                # 写入表格
+                # 表11--------------------------表11 土壤指标频度分析----------------------------------------
+                global resData_11
+                resData_11 = frequency_analysis(resData_12[['有效硅mg/kg', '有效铁mg/kg', '有效锰mg/kg', '有效铜mg/kg',
+                                                          '有效锌mg/kg', '有效硼mg/kg', '有效钼mg/kg']])
+
+                # 表14--------------------------表14 土壤重金属指标----------------------------------------
+                resData_14 = pd.DataFrame({
+                    '编号': simpleData['原样品编号'],
+                    '母质': simpleData['母质'],
+                    '土地利用类型': simpleData['土地利用类型'],
+                    'pH': simpleData['pH'],
+                    '镉mg/kg': simpleData['总镉'],
+                    '汞mg/kg': simpleData['总汞'],
+                    '砷mg/kg': simpleData['总砷'],
+                    '铅mg/kg': simpleData['总铅'],
+                    '铬mg/kg': simpleData['总铬'],
+                    '镍mg/kg': simpleData['总镍']
+                })
+                # 调用判断函数
+                res_value_14 = pb.last_metal(resData_14)
+                resData_14 = resData_14.reset_index(drop=True)
+                resData_14['审核结果'] = res_value_14['审核结果']
+                global resData_14_Style
+                global table_14_data
+                table_14_data = resData_14
+                # 提取异常数据
+                global table_14_index
+                table_14_index = pd.DataFrame({
+                    '样品编号': simpleData['样品编号'],
+                    '指标': res_value_14['异常指标'],
+                    '原因': res_value_14['审核结果']
+                })
+                resData_14_Style = resData_14.style.apply(highlight_condition, axis=1)
+                # 写入表格
+                # 表13--------------------------表13 土壤重金属频度分析----------------------------------------
+                global resData_13
+                print('resData_13---1', resData_13)
+                resData_13 = frequency_analysis(
+                    resData_14[['镉mg/kg', '汞mg/kg', '砷mg/kg', '铅mg/kg', '铬mg/kg', '镍mg/kg']])
+                print('resData_13--', resData_13)
+                show_info('文件审核完成,请点击保存按钮保存文件!')
+        else:
+            #提示文件为空 重新选择
+            print("Excel 文件为空。")
+    except Exception as err:
+        print('审核过程中出错!', err)
+        show_error('审核过程中出错!')
+
+
+def makeNormalWord(url):
+    # 根据提取数据 合并数据 生成报告
+    length = len(table_1_index)
+    emptyArr = [np.nan for i in range(length)]
+    indexArr = pd.RangeIndex(start=1, stop=length+1)
+    newData = pd.DataFrame({
+        '序号': indexArr,
+        '样品编号': table_1_index['样品编号'],
+        '土地利用类型': table_1_index['土地利用类型'],
+        '指标': table_1_index['指标'] + table_3_index['指标'] + table_5_index['指标'] + table_8_index['指标'] + table_10_index['指标'] + table_12_index['指标'] + table_14_index['指标'],
+        '原因': table_1_index['原因'] + table_3_index['原因'] + table_5_index['原因'] + table_8_index['原因'] + table_10_index['原因'] + table_12_index['原因'] + table_14_index['原因'],
+        '结合外业调查及相关信息评价': emptyArr,
+        '数据判定': emptyArr
+    })
+    newData = newData.replace(np.nan, '')
+    name = os.path.basename(changeFileUrl)
+    n = name.split('.')
+    areaName = n[0].replace('数据', '')
+    # 新建文档
+    doc = Document()
+    # 添加标题
+    doc.add_heading(f"{areaName}数据审核过程存疑数据一览表", level=0).bold = True
+    table_1 = doc.add_table(rows=length + 1, cols=7, style='Light Shading Accent 1')
+    table_1.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(newData.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(newData.iloc[i - 1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 保存文件
+    doc.save(f'{url}/{areaName}存疑数据一览表.docx')
+
+################一下是GUI部分-----------------------------------------------------------------------------
+
+# 选择文件
+def open_file():
+    # 这里限制只能取 excel文件
+    filetypes = (
+        ('excel files', '*.xlsx'),
+        ('All files', '*.xlsx*')
+    )
+
+    filename = filedialog.askopenfilename(
+        title='选择文件',
+        initialdir='/',
+        filetypes=filetypes)
+
+    # 这里增加判断 若文件为空提示错误
+    simpleData = pd.read_excel(filename)
+    if not simpleData.empty:
+        global changeFileUrl
+        changeFileUrl = filename
+        titleList = ['序号',	'原样品编号',	'样品编号','地理位置','土壤类型','母岩','母质','土地利用类型','洗失量(吸管法需填)',
+                     '2~0.2mm颗粒含量','0.2~0.02mm颗粒含量','0.02~0.002mm颗粒含量','0.002mm以下颗粒含量','土壤质地',
+                     '风干试样含水量(分析基)','pH','阳离子交换量','交换性盐基总量','交换性钙','交换性镁','交换性钠',
+                     '交换性钾','全盐量','电导率','水溶性Na⁺含量','水溶性K⁺含量','水溶性Ca²⁺含量','水溶性Mg²⁺含量',
+                     '水溶性Cl⁻含量','水溶性CO₃²⁻含量','水溶性HCO₃⁻含量','水溶性SO₄²⁻含量', '离子总量','有机质','全氮',
+                     '全磷','全钾','全硒','有效磷','速效钾','缓效钾',	'有效硫','有效硅','有效铁',	'有效锰','有效铜','有效锌',
+                     '有效硼','有效钼','碳酸钙','总汞','总砷','总铅','总镉','总铬','总镍','土壤容重1(g/cm³)','土壤容重2(g/cm³)',
+                     '土壤容重3(g/cm³)','土壤容重4(g/cm³)','土壤容重平均值(g/cm³)','水稳>5mm(%)','水稳3mm~5mm(%)',
+                     '水稳2mm~3mm(%)','水稳1mm~2mm(%)','水稳0.5mm~1mm(%)','水稳0.25mm~0.5mm(%)','水稳性大团聚体总和(%)']
+        # 也可以增加文件内容判断 格式不正确 提示错误 这里验证表头
+        errList = []
+        for item in simpleData.columns:
+            if item not in titleList:
+                errList.append(item)
+        if len(errList) > 0:
+            show_info(f'{errList}以上指标格式错误,请按照以下格式重新填写表头:{titleList}以保证审核流程正确执行!')
+        else:
+            # 验证通过 提示框展示文件名称
+            show_info('文件选择完成,点击审核按钮开始审核!')
+    else:
+        show_error('文件为空,请检查文件!')
+
+
+# 设置字体的函数
+def set_font(cell):
+    cell.paragraphs[0].runs[0].font.name = "Times New Roman"  # 设置英文字体
+    cell.paragraphs[0].runs[0].font.size = Pt(9)  # 字体大小
+    cell.paragraphs[0].runs[0]._element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')  # 设置中文字体
+
+# 生成报告
+def getReport(data,changeFileUrl, saveFileUrl, check_1_data,
+    check_3_data,
+    check_5_data ,
+    check_8_data,  # 样品编号替换为编号
+    check_10_data,
+    check_12_data,
+    check_14_data ):
+    # 根据选择的路径读取数据
+    data['原样品编号'] = data['原样品编号'].astype(str)
+    # checkData = pd.read_excel(changeFileUrl, sheet_name='检测方法')
+    # 生成报告
+    name = os.path.basename(changeFileUrl)
+    n = name.split('.')
+    areaName = n[0].replace('数据', '')
+    # 生成一个新的文件夹用于存放审核报告相关的数据
+    nowTime = time.strftime("%Y-%m-%d %H时%M分%S秒", time.localtime())
+    dir_name = f'{areaName}数据审核报告'
+    mkdir_path = saveFileUrl + '/' + dir_name + nowTime
+    if not os.path.exists(mkdir_path):
+        os.mkdir(mkdir_path)
+    # 上面这个地址,可以纯递给函数中,用于保存表格和图片
+    # 调用函数 开始生成报告相关内容
+    # 表1相关数据
+    typeData = report.getSimpleNum(data)
+    lenNum_1 = len(typeData['sData'])
+    lenNum_1_f = len(typeData['allData'])
+    table_1_data = pd.DataFrame({
+        '类型': typeData['sData'].index,
+        '数量': typeData['sData'],
+        '合计': [typeData['sData'].sum() for _ in range(lenNum_1)]
+    })
+    # 表2数据
+    table_2_data = report.getDataComplete(data)
+    table_2_data = table_2_data.reset_index()
+    table_2_data.columns = ['指标名称', '实测数量', '应测数量']
+    # 表3数据
+    # table_3_data = report.checkMethod(checkData, mkdir_path)
+    # 数据修约 表4
+    report.getNum(data, mkdir_path)
+    # 数据填报项审核 表5
+    report.dataReportResult(data, mkdir_path)
+    # 表6数据 土壤质地类型不一致
+    middData = data[['原样品编号', '样品编号']].astype(str)
+    middData['编号'] = middData['原样品编号']
+    del middData['原样品编号']
+    check_1_data = pd.merge(check_1_data,middData, how='left', on='编号')
+    check_1_data = check_1_data.replace(np.nan,'')
+    typeNotSame = check_1_data[check_1_data['土壤质地'] != check_1_data['土壤类型(判断)']]
+    table_6_data = typeNotSame[['编号','样品编号', '土壤质地', '土壤类型(判断)']]
+
+    allNeedData = pd.DataFrame({})
+    allNeedData['原样品编号'] = check_1_data['编号']
+    getSimpleDataNumber = pd.merge(allNeedData, data[['原样品编号', '样品编号']], how='left', on="原样品编号")
+    allNeedData['样品编号'] = getSimpleDataNumber['样品编号']
+    allNeedData['土地利用类型'] = check_1_data['土地利用类型']
+    allNeedData['审核结果'] = check_1_data['审核结果'] + check_3_data['审核结果'] + check_5_data['审核结果'] + check_8_data['审核结果'] + check_10_data['审核结果'] + check_12_data['审核结果'] + check_14_data['审核结果']
+    allNeedData['外业'] = ['' for _ in range(len(check_1_data))]
+    table_7_data = allNeedData[allNeedData['审核结果'] != '']
+    del table_7_data['审核结果']
+    # 写进表格
+    with pd.ExcelWriter(f'{mkdir_path}/超阈值样品统计表.xlsx', engine='openpyxl') as writer:
+        table_7_data.to_excel(writer, index=False, sheet_name='超阈值数据')
+    # 表8数据
+    table_8_data = report.getPHData(data, mkdir_path)
+    # 表10 数据
+    table_10_data = report.getNAndC(data, mkdir_path)
+    # 表11 数据:全磷和有效磷异常数据统计
+    table_11_data = report.getPData(data, mkdir_path)
+    # 表12数据 重金属超标
+    caOverData = pd.merge(check_1_data[['编号','土地利用类型']],check_14_data[['编号','pH','镉mg/kg','汞mg/kg',	'砷mg/kg','铅mg/kg',	'铬mg/kg','镍mg/kg',	'审核结果']] , how='outer', on=['编号'])
+    caOverData['原样品编号'] = caOverData['编号']
+    caOverData = pd.merge(caOverData, data[['原样品编号', '样品编号']], how='left', on='原样品编号')
+    first_column = caOverData.pop('样品编号')
+    caOverData.insert(0, '样品编号', first_column)
+    caOverData_need = caOverData[caOverData['审核结果'] != '']
+    report.getKData(data, mkdir_path)
+    report.cationExchangeCapacity(data,mkdir_path)
+    report.changeCation(data, mkdir_path)
+    report.manyTypes(data, mkdir_path)
+    # 写进表格
+    with pd.ExcelWriter(f'{mkdir_path}/重金属超筛选值情况统计.xlsx', engine='openpyxl') as writer:
+        caOverData_need.to_excel(writer, index=False, sheet_name='重金属超筛选值情况统计')
+    # 表13 所有存疑数据
+    with pd.ExcelWriter(f'{mkdir_path}/数据审核过程存疑数据一览表.xlsx', engine='openpyxl') as writer:
+        allNeedData[allNeedData['审核结果'] != ''].to_excel(writer, index=False, sheet_name='存疑数据')
+    # 附表: 频度分析图
+    report.getFrequencyImage(data, mkdir_path)
+    table_f_2_data = report.getFrequencyInformation(data, mkdir_path)
+    print('table_f_2_data---', table_f_2_data)
+    # 新建一个文档
+    doc = Document()
+    # 添加标题
+    doc.add_heading(f"{areaName}第三次全国土壤普查数据审核报告", level=0)
+    # 添加一级标题
+    doc.add_heading('一、数据完整性审核', level=1)
+    doc.add_heading('1、土地利用类型与检测指标符合性审核', level=2)
+    # 插入表格1
+    paragraph_1 = doc.add_paragraph()
+    paragraph_1.add_run(f"表1:{areaName}三普样品数量统计表(表层)").bold = True
+    # 设置居中
+    paragraph_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_1 = doc.add_table(rows=lenNum_1 +1, cols=3, style='Light Shading Accent 1')
+    table_1.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i-1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    #合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 > 1:
+        table_1.cell(2, 2).text= ''
+        table_1.cell(1, 2).merge(table_1.cell(2, 2))
+    # table_1.cell(1, 2).vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
+    # table_1.cell(2, 2).vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
+    ############test##############
+    doc.add_heading('2、指标名称与实际检测样品数量完整性审核', level=2)
+    # 插入表格2
+    paragraph_2 = doc.add_paragraph()
+    paragraph_2.add_run(f'表2:{areaName}指标名称与实际检测样品数量统计表').bold = True
+    table_2 = doc.add_table(rows=len(table_2_data) + 1, cols=3, style='Light Shading Accent 1')
+    paragraph_2.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_2.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_2_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_2_data.iloc[i-1, j]))
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+
+    doc.add_heading('二、数据规范性审核', level=1)
+    doc.add_heading('1、数据填报规范性审核', level=2)
+    # 插入表3
+    paragraph_3 = doc.add_paragraph()
+    paragraph_3.add_run(f'表3:{areaName}土壤检测数据检测方法填报审核结果表').bold = True
+    # table_3 = doc.add_table(rows=2, cols=2)
+    paragraph_3.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_3.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据写不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:检测方法审核结果.xlsx', level=4)
+    doc.add_heading('2、数值修约规范性审核', level=2)
+    # 插入表4
+    paragraph_4 = doc.add_paragraph()
+    paragraph_4.add_run(f'表4:{areaName}土壤检测数据数值修约结果表').bold = True
+    # table_4 = doc.add_table(rows=2, cols=2)
+    paragraph_4.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_4.alignment = WD_TABLE_ALIGNMENT.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数值修约审核.xlsx', level=4)
+    # 填入数据 这里数据也放不下 嵌入链接
+    doc.add_heading('3、数据未检出的填报规范性审核', level=2)
+    # 插入表5
+    paragraph_5 = doc.add_paragraph()
+    paragraph_5.add_run(f'表5:{areaName}土壤检测数据未检出项填报审核结果表').bold = True
+    # table_5 = doc.add_table(rows=2, cols=2)
+    paragraph_5.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_5.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 这里数据也放不下 嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据填报项审核结果.xlsx', level=4)
+    doc.add_heading('4、土壤质地填报规范性审核', level=2)
+    # 插入表6
+    paragraph_6 = doc.add_paragraph()
+    paragraph_6.add_run(f'表6:{areaName}土壤质地填报审核结果表').bold = True
+    table_6 = doc.add_table(rows=len(table_6_data)+1, cols=4, style='Light Shading Accent 1')
+    paragraph_6.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_6.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 提取结果表中数据
+    # 写入数据 土壤质地类型不一致的数据提取出来
+    for i, row in enumerate(table_6.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_6_data.columns[j]))
+                r.font.bold = True
+            else:
+                r=paragraph.add_run(str(table_6_data.iloc[i-1, j]))
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1 # 段落行间距
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    doc.add_heading('三、数据合理性审核', level=1)
+    doc.add_heading('1、阈值法审核', level=2)
+    # 插入表格
+    paragraph_7 = doc.add_paragraph()
+    paragraph_7.add_run(f'表7:{areaName}土壤检测数据超阈值样品统计表').bold = True
+    # table_7 = doc.add_table(rows=2, cols=2)
+    # paragraph_7.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # table_7.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 写入数据 点击查看数据 这里也不一定写的下 最好是嵌入链接
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据审核过程存疑数据一览表.xlsx', level=4)
+    # todo 合并所有数据 审核结果不为空的数据 写入表格保存到指定文件夹
+    doc.add_heading('2、极值法审核', level=2)
+    doc.add_heading('(1)pH', level=3)
+    # 插入ph分布图
+    if os.path.isfile(f'{mkdir_path}/PH值分布图.png'):
+        doc.add_picture(f'{mkdir_path}/PH值分布图.png', width=Inches(6.0))
+    paragraph_t_1 = doc.add_paragraph()
+    paragraph_t_1.add_run(f'图1:pH值分布情况').bold = True
+    paragraph_t_1.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # 插入频度统计表
+    paragraph_8 = doc.add_paragraph()
+    paragraph_8.add_run('表8:pH数据统计表').bold = True
+    table_8 = doc.add_table(rows=6, cols=2, style='Light Shading Accent 1')
+    t_8 = table_8_data['频度分析']
+    t_8 = t_8.reset_index()
+    t_8.columns = ['指标', '数据']
+    paragraph_8.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    table_8.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_8.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(t_8.columns[j]))
+                r.font.bold = True
+            else:
+                r=paragraph.add_run(str(t_8.iloc[i-1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 插入异常数据提取表格 todo 这里数据多的话也可能写不下 最好是嵌入一
+    t_9 = table_8_data['异常数据']
+    if not t_9.empty:
+        paragraph_9 = doc.add_paragraph()
+        paragraph_9.add_run('表9:pH异常数据统计表').bold = True
+        table_9 = doc.add_table(rows=len(table_8_data['异常数据']) + 1, cols=6, style='Light Shading Accent 1')
+        paragraph_9.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_9.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_9.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(t_9.columns[j]))
+                    r.font.bold = True
+                else:
+                    r=paragraph.add_run(str(t_9.iloc[i-1, j]))
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    doc.add_heading('3、关联分析法审核', level=2)
+    if os.path.isfile(f'{mkdir_path}/有机质与全氮相关性分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有机质与全氮相关性分析图.png', width=Inches(6.0))
+    paragraph_t_2 = doc.add_paragraph()
+    paragraph_t_2.add_run(f'图2:有机质与全氮相关关系').bold = True
+    paragraph_t_2.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # 插入碳氮比异常数据
+    if not table_10_data.empty:
+        paragraph_10 = doc.add_paragraph()
+        paragraph_10.add_run('表10:碳氮比异常数据统计表').bold = True
+        table_10 = doc.add_table(rows=len(table_10_data)+1, cols=8, style='Light Shading Accent 1')
+        paragraph_10.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_10.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_10.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(table_10_data.columns[j]))
+                    r.font.bold = True
+                else:
+                    r=paragraph.add_run(str(table_10_data.iloc[i-1, j]))
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    doc.add_heading('4、指标综合分析', level=2)
+    # 插入图片
+    if os.path.isfile(f'{mkdir_path}/全磷分布图.png'):
+        doc.add_picture(f'{mkdir_path}/全磷分布图.png', width=Inches(6.0))
+    paragraph_t_3 = doc.add_paragraph()
+    paragraph_t_3.add_run(f'图3:全磷分布图').bold = True
+    paragraph_t_3.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    if os.path.isfile(f'{mkdir_path}/有效磷分布图.png'):
+        doc.add_picture(f'{mkdir_path}/有效磷分布图.png', width=Inches(6.0))
+    paragraph_t_4 = doc.add_paragraph()
+    paragraph_t_4.add_run(f'图4:有效磷分布图').bold = True
+    paragraph_t_4.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # 插入图片
+    if os.path.isfile(f'{mkdir_path}/有效磷占全磷比分布图.png'):
+        doc.add_picture(f'{mkdir_path}/有效磷占全磷比分布图.png', width=Inches(6.0))
+    paragraph_t_5 = doc.add_paragraph()
+    paragraph_t_5.add_run(f'图5:有效磷含量占全磷含量比例').bold = True
+    paragraph_t_5.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # 插入表格
+    if not table_11_data.empty:
+        paragraph_11 = doc.add_paragraph()
+        paragraph_11.add_run('表11:全磷与有效磷异常样品统计表').bold = True
+        table_11 = doc.add_table(rows=len(table_11_data)+1, cols=7, style='Light Shading Accent 1')
+        paragraph_11.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        table_11.alignment = WD_TABLE_ALIGNMENT.CENTER
+        for i, row in enumerate(table_11.rows):
+            for j, cell in enumerate(row.cells):
+                # 获取单元格中的段落对象
+                paragraph = cell.paragraphs[0]
+                if i == 0:
+                    r = paragraph.add_run(str(table_11_data.columns[j]))
+                    r.font.bold = True
+                else:
+                    r=paragraph.add_run(str(table_11_data.iloc[i-1, j]))
+
+                r.font.size = Pt(10.5)
+                r.font.name = 'Times New Roman'
+                r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+                paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+                paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    else:
+        paragraph_11 = doc.add_paragraph()
+        paragraph_11.add_run('表11:全磷与有效磷异常样品统计表').bold = True
+        paragraph_11_info = doc.add_paragraph()
+        paragraph_11_info.add_run('无异常数据')
+        paragraph_11.alignment = WD_ALIGN_PARAGRAPH.CENTER
+        paragraph_11_info.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # 全钾、速效钾、缓效钾
+    if os.path.isfile(f'{mkdir_path}/全钾与速效钾缓效钾之和关系统计图.png'):
+        doc.add_picture(f'{mkdir_path}/全钾与速效钾缓效钾之和关系统计图.png', width=Inches(6.0))
+    paragraph_t_6 = doc.add_paragraph()
+    paragraph_t_6.add_run(f'图6:全钾与速效钾缓效钾之和关系统计图').bold = True
+    paragraph_t_6.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/速效钾与缓效钾关系统计图.png'):
+        doc.add_picture(f'{mkdir_path}/速效钾与缓效钾关系统计图.png', width=Inches(6.0))
+    paragraph_t_7 = doc.add_paragraph()
+    paragraph_t_7.add_run(f'图7:速效钾与缓效钾关系统计图').bold = True
+    paragraph_t_7.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    doc.add_heading('表12:重金属超筛选值情况统计', level=4)
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:重金属超筛选值情况统计表.xlsx', level=4)
+    # todo 获取重金属数据
+    # 阳离子交换量与交换性盐总量关系
+    if os.path.isfile(f'{mkdir_path}/阳离子交换量与交换性盐基总量相关关系.png'):
+        doc.add_picture(f'{mkdir_path}/阳离子交换量与交换性盐基总量相关关系.png', width=Inches(6.0))
+    paragraph_t_8 = doc.add_paragraph()
+    paragraph_t_8.add_run(f'图8:阳离子交换量与交换性盐总量关系图').bold = True
+    paragraph_t_8.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    # 交换性盐总量与交换性盐相关关系
+    if os.path.isfile(f'{mkdir_path}/交换性盐基总量与交换性盐相关关系(pH小于等于7.5).png'):
+        doc.add_picture(f'{mkdir_path}/交换性盐基总量与交换性盐相关关系(pH小于等于7.5).png', width=Inches(6.0))
+    paragraph_t_9 = doc.add_paragraph()
+    paragraph_t_9.add_run(f'图9:交换性盐基总量和交换性钙镁钠钾分项指标关系(pH≤7.5)').bold = True
+    paragraph_t_9.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/交换性盐基总量与交换性盐相关关系(pH大于7.5).png'):
+        doc.add_picture(f'{mkdir_path}/交换性盐基总量与交换性盐相关关系(pH大于7.5).png', width=Inches(6.0))
+    paragraph_t_10 = doc.add_paragraph()
+    paragraph_t_10.add_run(f'图10:交换性盐基总量和交换性钙镁钠钾分项指标关系(pH大于7.5)').bold = True
+    paragraph_t_10.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    # 水溶性盐、电导率、离子总量
+    if os.path.isfile(f'{mkdir_path}/全盐量分布图.png'):
+        doc.add_picture(f'{mkdir_path}/全盐量分布图.png', width=Inches(6.0))
+    paragraph_t_11 = doc.add_paragraph()
+    paragraph_t_11.add_run(f'图11:全盐量分布图').bold = True
+    paragraph_t_11.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/全盐量与电导率相关性分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全盐量与电导率相关性分析图.png', width=Inches(6.0))
+    paragraph_t_12 = doc.add_paragraph()
+    paragraph_t_12.add_run(f'图12:全盐量与电导率相关性分析图').bold = True
+    paragraph_t_12.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    if os.path.isfile(f'{mkdir_path}/离子总量与水溶性盐总量关系图.png'):
+        doc.add_picture(f'{mkdir_path}/离子总量与水溶性盐总量关系图.png', width=Inches(6.0))
+    paragraph_t_13 = doc.add_paragraph()
+    paragraph_t_13.add_run(f'图13:水溶性盐总量与离子总量关系分析图').bold = True
+    paragraph_t_13.alignment = WD_ALIGN_PARAGRAPH.CENTER
+
+    doc.add_heading('四、审核存疑数据', level=1)
+    paragraph_12 = doc.add_paragraph()
+    paragraph_12.add_run(f'表13:数据审核过程存疑数据一览表').bold = True
+    paragraph_12.alignment = WD_ALIGN_PARAGRAPH.CENTER
+    doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:数据审核过程存疑数据一览表.xlsx', level=4)
+    doc.add_heading('五、附表', level=1)
+    doc.add_heading('附表1:某区三普样品数量统计表(表层)', level=2)
+    # 插入附表1
+    table_1_f = doc.add_table(rows=lenNum_1 +1, cols=3, style='Light Shading Accent 1')
+    table_1_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+    # 遍历表格 插入数据
+    # 遍历表格的所有单元格,并填充内容
+    for i, row in enumerate(table_1_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(table_1_data.columns[j]))
+                r.font.bold = True
+            else:
+                r = paragraph.add_run(str(table_1_data.iloc[i-1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    #合并单元格 合并第3列的第二行和第三行
+    if lenNum_1 >1 :
+        table_1_f.cell(2, 2).text = ''
+        table_1_f.cell(1, 2).merge(table_1_f.cell(2, 2))
+    doc.add_heading('附表2:各指标频度分析表', level=2)
+    # 插入表格 写入数据
+    table_f_2_data = table_f_2_data.replace(np.nan, '')
+    # table_f_2 = doc.add_table(rows=len(table_f_2_data)+1, cols=6, style='Light Shading Accent 1')
+    rows = (int(len(table_f_2_data.columns) / 6)+1)
+    columnsList = np.arange(0, rows * 6, 6)
+    dataList = []
+
+    for i in columnsList:
+        res = table_f_2_data.iloc[:, i:i + 6]
+        res = res.reset_index()
+        dataList.append(res)
+    table_f_2 = doc.add_table(rows=rows * 6, cols=7, style='Light Shading Accent 1')
+    for i, row in enumerate(table_f_2.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == columnsList[0]:
+                # 第一行 显示前6个指标的列名
+                if len(dataList[0].columns) > j:
+                    r = paragraph.add_run(dataList[0].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 1 and i > columnsList[0] and i < columnsList[1]:
+                if len(dataList[0].columns) > j:
+                    r = paragraph.add_run(str(dataList[0].iloc[i - 1, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[1]:
+                # 第6行 显示前6个指    标的列名
+                if len(dataList[1].columns) > j:
+                    r = paragraph.add_run(dataList[1].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 2 and i > columnsList[1] and i < columnsList[2]:
+                if len(dataList[1].columns) > j:
+                    r = paragraph.add_run(str(dataList[1].iloc[i - 7, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[2]:
+                # 第6*2行 显示前6个指    标的列名
+                if len(dataList[2].columns) > j:
+                    r = paragraph.add_run(dataList[2].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 3 and i > columnsList[2] and i < columnsList[3]:
+                if len(dataList[2].columns) > j:
+                    r = paragraph.add_run(str(dataList[2].iloc[i - 13, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[3]:
+                # 第6*3行 显示前6个指    标的列名
+                if len(dataList[3].columns) > j:
+                    r = paragraph.add_run(dataList[3].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 4 and i > columnsList[3] and i < columnsList[4]:
+                if len(dataList[3].columns) > j:
+                    r = paragraph.add_run(str(dataList[3].iloc[i - 19, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[4]:
+                # 第6*4行 显示前6个指    标的列名
+                if len(dataList[4].columns) > j:
+                    r = paragraph.add_run(dataList[4].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 5 and i > columnsList[4] and i < columnsList[5]:
+                if len(dataList[4].columns) > j:
+                    r = paragraph.add_run(str(dataList[4].iloc[i - 25, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[5]:
+                # 第6*5行 显示前6个指 标的列名
+                if len(dataList[5].columns) > j:
+                    r = paragraph.add_run(dataList[5].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 6 and i > columnsList[5] and i < columnsList[6]:
+                if len(dataList[5].columns) > j:
+                    r = paragraph.add_run(str(dataList[5].iloc[i - 31, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[6]:
+                # 第6*6行 显示前6个指    标的列名
+                if len(dataList[6].columns) > j:
+                    r = paragraph.add_run(dataList[6].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) > 7 and i > columnsList[6] and i < columnsList[7]:
+                if len(dataList[6].columns) > j:
+                    r = paragraph.add_run(str(dataList[6].iloc[i - 37, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[7]:
+                # 第6*7行 显示前6个指    标的列名
+                if len(dataList[7].columns) > j:
+                    r = paragraph.add_run(dataList[7].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) >= 8 and i > columnsList[7] and i < columnsList[8]:
+                if len(dataList[7].columns) > j:
+                    r = paragraph.add_run(str(dataList[7].iloc[i - 43, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[8]:
+                if len(dataList[8].columns) > j:
+                    # 第6*8行 显示前6个指    标的列名
+                    r = paragraph.add_run(dataList[8].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) >= 9 and i > columnsList[8] and i < columnsList[9]:
+                if len(dataList[8].columns) > j:
+                    r = paragraph.add_run(str(dataList[8].iloc[i - 49, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif i == columnsList[9]:
+                # 第6*9行 显示前6个指    标的列名
+                if len(dataList[9].columns) > j:
+                    r = paragraph.add_run(dataList[9].columns[j])
+                    r.font.bold = True
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            elif len(columnsList) >= 10 and i > columnsList[9] and i <= 60:
+                if len(dataList[9].columns) > j:
+                    print(dataList[9].columns)
+                    print(str(dataList[9].iloc[i - 55, j]))
+                    r = paragraph.add_run(str(dataList[9].iloc[i - 55, j]))
+                    r.font.size = Pt(10.5)
+                    r.font.name = 'Times New Roman'
+                    r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+                else:
+                    paragraph.add_run('')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+
+    # for i, row in enumerate(table_f_2.rows):
+    #     for j, cell in enumerate(row.cells):
+    #         # 获取单元格中的段落对象
+    #         paragraph = cell.paragraphs[0]
+    #         if i == 0:
+    #             r = paragraph.add_run(str(table_f_2_data.columns[j]))
+    #             r.font.bold = True
+    #         else:
+    #             r=paragraph.add_run(str(table_f_2_data.iloc[i-1, j]))
+    #         r.font.size = Pt(10.5)
+    #         r.font.name = 'Times New Roman'
+    #         r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    #         paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+    #         paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+    #         paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+
+    # doc.add_heading('为避免数据量过多无法显示,请至数据保存文件夹中查看数据表:频度分析表.xlsx', level=4)
+    doc.add_heading('附表3:各指标频度分析图', level=2)
+    # 插入频度信息的图形
+    if os.path.isfile(f'{mkdir_path}/0.002mm以下颗粒含量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/0.002mm以下颗粒含量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/0.02~0.002mm颗粒含量分析图.png.png'):
+        doc.add_picture(f'{mkdir_path}/0.02~0.002mm颗粒含量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/0.2~0.02mm颗粒含量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/0.2~0.02mm颗粒含量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/2~0.2mm颗粒含量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/2~0.2mm颗粒含量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/pH分析图.png'):
+        doc.add_picture(f'{mkdir_path}/pH分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/电导率分析图.png'):
+        doc.add_picture(f'{mkdir_path}/电导率分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/风干试样含水量(分析基)分析图.png'):
+        doc.add_picture(f'{mkdir_path}/风干试样含水量(分析基)分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/缓效钾分析图.png'):
+        doc.add_picture(f'{mkdir_path}/缓效钾分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性钙分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性钙分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性钾分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性钾分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性镁分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性镁分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性钠分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性钠分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/交换性盐基总量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/交换性盐基总量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/全氮分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全氮分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/全钾分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全钾分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/全磷分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全磷分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/全盐量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/全盐量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/速效钾分析图.png'):
+        doc.add_picture(f'{mkdir_path}/速效钾分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/洗失量(吸管法需填)分析图.png'):
+        doc.add_picture(f'{mkdir_path}/洗失量(吸管法需填)分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/阳离子交换量分析图.png'):
+        doc.add_picture(f'{mkdir_path}/阳离子交换量分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有机质分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有机质分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效硅分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效硅分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效磷分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效磷分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效硫分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效硫分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效锰分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效锰分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效钼分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效钼分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效硼分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效硼分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效铁分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效铁分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效铜分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效铜分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/有效锌分析图.png'):
+        doc.add_picture(f'{mkdir_path}/有效锌分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总镉分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总镉分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总铬分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总铬分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总汞分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总汞分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总镍分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总镍分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总砷分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总砷分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/总铅分析图.png'):
+        doc.add_picture(f'{mkdir_path}/总铅分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重1分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重1分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重2分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重2分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重3分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重3分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重4分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重4分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/土壤容重平均值分析图.png'):
+        doc.add_picture(f'{mkdir_path}/土壤容重平均值分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳0.5mm~1mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳0.5mm~1mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳0.25mm~0.5mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳0.25mm~0.5mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳1mm~2mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳1mm~2mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳2mm~3mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳2mm~3mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳3mm~5mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳3mm~5mm分析图.png', width=Inches(6.0))
+    if os.path.isfile(f'{mkdir_path}/水稳5mm分析图.png'):
+        doc.add_picture(f'{mkdir_path}/水稳5mm分析图.png', width=Inches(6.0))
+    doc.add_heading('附表4:数值修约标准', level=2)
+    # 读取数据 插入表格 写入数据
+    numData = pd.read_excel('./img/数值修约要求.xlsx', sheet_name='Sheet1')
+    table_2_f = doc.add_table(rows=len(numData)+1, cols=2, style='Light Shading Accent 1')
+    table_2_f.alignment = WD_TABLE_ALIGNMENT.CENTER
+    for i, row in enumerate(table_2_f.rows):
+        for j, cell in enumerate(row.cells):
+            # 获取单元格中的段落对象
+            paragraph = cell.paragraphs[0]
+            if i == 0:
+                r = paragraph.add_run(str(numData.columns[j]))
+                r.font.bold = True
+            else:
+                r=paragraph.add_run(str(numData.iloc[i-1, j]))
+            r.font.size = Pt(10.5)
+            r.font.name = 'Times New Roman'
+            r.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
+            paragraph.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 对齐
+            paragraph.paragraph_format.line_spacing = 1  # 段落行间距
+    # 处理样式 遍历所有的段落 修改字体
+    # 遍历并打印每个段落的文本
+    paragraphs = doc.paragraphs
+    for paragraph in paragraphs:
+        for run in paragraph.runs:
+            run.font.color.rgb = RGBColor(0, 0, 0)
+            run.font.name = 'Times New Roman'
+            run.font.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+
+            # run.element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋_GB2312')
+    # 保存Word文档
+    doc.save(f'{mkdir_path}/{areaName}审核报告.docx')
+
+
+# 预处理数据
+def dealData(data):
+    simpleData = data.dropna(subset=['原样品编号'])
+    simpleData = simpleData[~simpleData['原样品编号'].str.contains('ZK')]
+    simpleData = simpleData.replace(r'[^.\w]+', '', regex=True)
+    # print('simpleData',simpleData)
+    simpleData = simpleData.replace('未检测', np.nan)
+    simpleData = simpleData.replace('', np.nan)
+    simpleData.iloc[:, 3:] = simpleData.iloc[:, 3:].apply(pd.to_numeric, errors='ignore')
+    strList = ['原样品编号', '样品编号', '地理位置', '土壤类型', '母质', '土地利用类型', '土壤质地']
+    for i in simpleData.columns:
+        if i not in strList:
+            simpleData[i] = pd.to_numeric(simpleData[i], errors='ignore')
+    # 处理重复样品
+    res = getRepeat(simpleData)
+    simpleData = simpleData._append(res).drop_duplicates(subset=['原样品编号'], keep='last')
+
+    return simpleData
+
+
+# 保存文件 可选择保存路径
+def saveFile():
+    # 根据选择的路径 保存文件
+    folder_selected = filedialog.askdirectory()
+    # 如果用户选择了文件夹,则打印路径
+    try:
+        if folder_selected:
+            # 新建一个文件夹
+            # 获取当前时间
+            nowTime = time.strftime("%Y-%m-%d %H时%M分%S秒", time.localtime())
+            dir_name = '土壤数据审核结果'
+            mkdir_path = folder_selected + '/' + dir_name + nowTime
+            global saveFileUrl
+            saveFileUrl = folder_selected
+            if not os.path.exists(mkdir_path):
+                os.mkdir(mkdir_path)
+            # 统一写入表格
+            # 创建一个html文件夹 保存图表
+                # 将 HTML 保存到文件
+            for i in htmlContent:
+                output_html_path = mkdir_path + '/'+ i['name'] + '.html'
+                with open(output_html_path, 'w', encoding='utf-8') as html_file:
+                    html_file.write(i['content'])
+            # 生成存疑数据表
+            makeNormalWord(mkdir_path)
+            # 表1 表2 土壤容重机械组成数据 土壤容重与机械组成总体数据频度分析
+            with pd.ExcelWriter(mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx', engine='openpyxl') as writer:
+                resData_1_Style.to_excel(writer, index=False, sheet_name='土壤容重数据')
+                resData_2.to_excel(writer,  sheet_name='频度分析')
+            autoColumns(mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx')
+            # 保存并写入频度统计图
+            nowTable = pd.read_excel(mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx',sheet_name='土壤容重数据')
+            getStatisticsImg(nowTable['土壤容重平均值(g/cm3)(计算)'],'土壤容重(g/cm3)','土壤容重',mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx',mkdir_path,'B19')
+            getStatisticsImg(nowTable['洗失量(吸管法需填)%'],'洗失量(吸管法需填)%','洗失量',mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx',mkdir_path,'C19')
+            getStatisticsImg(nowTable['2-0.2mm颗粒含量%'],'2-0.2mm颗粒含量%','2-0.2mm颗粒含量%',mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx',mkdir_path,'D19')
+            getStatisticsImg(nowTable['0.2-0.02mm颗粒含量%'],'0.2~0.02mm颗粒含量%','0.2~0.02mm颗粒含量%',mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx',mkdir_path,'E19')
+            getStatisticsImg(nowTable['0.02-0.002mm颗粒含量%'],'0.02~0.002mm颗粒含量%','0.02~0.002mm颗粒含量%',mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx',mkdir_path,'F19')
+            getStatisticsImg(nowTable['0.002mm以下颗粒含量%'],'0.002mm以下颗粒含量%','0.002mm以下颗粒含量%',mkdir_path + '/土壤容重数据-' + nowTime +'.xlsx',mkdir_path,'G19')
+            # 表3 表4
+            with pd.ExcelWriter(mkdir_path + '/水稳性大团聚体数据-' + nowTime +'.xlsx', engine='openpyxl') as writer:
+                resData_3_Style.to_excel(writer, index=False, sheet_name='水稳性大团聚体数据')
+                resData_4.to_excel(writer,  sheet_name='频度分析')
+            autoColumns(mkdir_path + '/水稳性大团聚体数据-' + nowTime +'.xlsx')
+            # 保存并写入频度统计图
+            nowTable_sw = pd.read_excel(mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx', sheet_name='水稳性大团聚体数据')
+            imgData = nowTable_sw.dropna(subset=['有机质g/kg','总和(%)'])
+            if not imgData['有机质g/kg'].empty and not imgData['总和(%)'].empty:
+                getImg(imgData['有机质g/kg'],imgData['总和(%)'],mkdir_path,
+                       '有机质与总和相关性分析图','水稳性大团聚体数据','有机质g/kg','总和(%)',imgData['编号'],
+                       mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx','N1')
+                getStatisticsImg(nowTable_sw['总和(%)'], '总和(%)', '总和(%)',
+                                 mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx', mkdir_path, 'B19')
+                getStatisticsImg(nowTable_sw['>5mm%'], '>5mm%', '>5mm%',
+                                 mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx', mkdir_path, 'C19')
+                getStatisticsImg(nowTable_sw['3-5mm%'], '3-5mm%', '3-5mm%',
+                                 mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx', mkdir_path, 'D19')
+                getStatisticsImg(nowTable_sw['2-3mm%'], '2-3mm%', '2-3mm%',
+                                 mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx', mkdir_path, 'E19')
+                getStatisticsImg(nowTable_sw['1-2mm%'], '1-2mm%', '1-2mm%',
+                                 mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx', mkdir_path, 'F19')
+                getStatisticsImg(nowTable_sw['0.5-1mm%'], '0.5-1mm%', '0.5-1mm%',
+                                 mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx', mkdir_path, 'G19')
+                getStatisticsImg(nowTable_sw['0.25-0.5mm%'], '0.25-0.5mm%', '0.25-0.5mm%',
+                                 mkdir_path + '/水稳性大团聚体数据-' + nowTime + '.xlsx', mkdir_path, 'H19')
+            # 表5 表6
+
+            with pd.ExcelWriter(mkdir_path + '/土壤离子数据-' + nowTime +'.xlsx', engine='openpyxl') as writer:
+                resData_5_Style.to_excel(writer, index=False, sheet_name='土壤离子数据')
+                resData_6.to_excel(writer, sheet_name='频度分析')
+            autoColumns(mkdir_path + '/土壤离子数据-' + nowTime +'.xlsx')
+            nowTable_lz= pd.read_excel(mkdir_path + '/土壤离子数据-' + nowTime + '.xlsx',
+                                        sheet_name='土壤离子数据')
+            getStatisticsImg(nowTable_lz['pH'], 'pH', 'pH',
+                             mkdir_path + '/土壤离子数据-' + nowTime + '.xlsx', mkdir_path, 'B19')
+            # 表7 表8
+
+            with pd.ExcelWriter(mkdir_path + '/土壤水溶性盐数据-' + nowTime +'.xlsx', engine='openpyxl') as writer:
+                resData_8_Style.to_excel(writer, index=False, sheet_name='水溶性盐数据')
+                resData_7.to_excel(writer,  sheet_name='频度分析')
+            autoColumns(mkdir_path + '/土壤水溶性盐数据-' + nowTime +'.xlsx')
+            nowTable_sr = pd.read_excel(mkdir_path + '/土壤水溶性盐数据-' + nowTime + '.xlsx',
+                                        sheet_name='水溶性盐数据')
+            imgData_sr = nowTable_sr.dropna(subset=['水溶性全盐量g/kg', '电导率ms/cm'])
+            getImg(imgData_sr['水溶性全盐量g/kg'],imgData_sr['电导率ms/cm'],mkdir_path,'水溶性盐电导率相关性分析图',
+                  '水溶性盐数据', '水溶性全盐量g/kg','电导率ms/cm',
+                   imgData_sr['样品编号'],mkdir_path + '/土壤水溶性盐数据-' + nowTime + '.xlsx','T1')
+            getStatisticsImg(nowTable_sr['水溶性全盐量g/kg'], '水溶性全盐量g/kg', '水溶性全盐量',
+                             mkdir_path + '/土壤水溶性盐数据-' + nowTime + '.xlsx', mkdir_path, 'B19')
+            getStatisticsImg(nowTable_sr['电导率ms/cm'], '电导率ms/cm', '电导率',
+                             mkdir_path + '/土壤水溶性盐数据-' + nowTime + '.xlsx', mkdir_path, 'C19')
+            # 表9 表10
+            with pd.ExcelWriter(mkdir_path + '/土壤氮磷钾数据-' + nowTime +'.xlsx', engine='openpyxl') as writer:
+                resData_10_Style.to_excel(writer, index=False, sheet_name='土壤氮磷钾数据')
+                resData_9.to_excel(writer,  sheet_name='频度分析')
+            autoColumns(mkdir_path + '/土壤氮磷钾数据-' + nowTime +'.xlsx')
+
+            nowTable_NPK = pd.read_excel(mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx',
+                                        sheet_name='土壤氮磷钾数据')
+            # 插入分析图
+            imgData_NPK = nowTable_NPK.dropna(subset=['有机质g/kg', '全氮g/kg'])
+            cationImgData = nowTable_NPK.dropna(subset=['有机质g/kg', '阳离子交换量'])
+            getImg(imgData_NPK['有机质g/kg'],imgData_NPK['全氮g/kg'],mkdir_path,'有机质和全氮相关性分析图','土壤氮磷钾数据',
+                   '有机质g/kg','全氮g/kg',imgData_NPK['编号'],mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx','P1')
+            getImg(cationImgData['有机质g/kg'], cationImgData['阳离子交换量'], mkdir_path, '有机质和阳离子交换量相关性分析图',
+                   '土壤氮磷钾数据',
+                   '有机质g/kg', '阳离子交换量', cationImgData['编号'], mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx',
+                   'P6')
+            getStatisticsImg(nowTable_NPK['有机质g/kg'], '有机质g/kg', '有机质',
+                             mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx', mkdir_path, 'B19')
+            getStatisticsImg(nowTable_NPK['全氮g/kg'], '全氮g/kg', '全氮',
+                             mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx', mkdir_path, 'C19')
+            getStatisticsImg(nowTable_NPK['全磷g/kg'], '全磷g/kg', '全磷',
+                             mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx', mkdir_path, 'D19')
+            getStatisticsImg(nowTable_NPK['有效磷g/kg'], '有效磷g/kg', '有效磷',
+                             mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx', mkdir_path, 'E19')
+            getStatisticsImg(nowTable_NPK['全钾g/kg'], '全钾g/kg', '全钾',
+                             mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx', mkdir_path, 'F19')
+            getStatisticsImg(nowTable_NPK['缓效钾mg/kg'], '缓效钾mg/kg', '缓效钾',
+                             mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx', mkdir_path, 'G19')
+            getStatisticsImg(nowTable_NPK['速效钾mg/kg'], '速效钾mg/kg', '速效钾',
+                             mkdir_path + '/土壤氮磷钾数据-' + nowTime + '.xlsx', mkdir_path, 'H19')
+            # 表11 表12
+
+            with pd.ExcelWriter(mkdir_path + '/土壤金属指标数据-' + nowTime +'.xlsx', engine='openpyxl') as writer:
+                resData_12_Style.to_excel(writer, index=False, sheet_name='土壤金属指标数据')
+                resData_11.to_excel(writer,  sheet_name='频度分析')
+            autoColumns(mkdir_path + '/土壤金属指标数据-' + nowTime +'.xlsx')
+
+            nowTable_js = pd.read_excel(mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx',
+                                         sheet_name='土壤金属指标数据')
+            # 插入相关性分析图
+            # 铁与ph相关性
+            imgDataF = nowTable_js.dropna(subset=['有效铁mg/kg', 'pH'])
+            getImg(imgDataF['有效铁mg/kg'], imgDataF['pH'], mkdir_path, '有效铁与ph相关性分析图',
+                   '土壤金属指标数据',
+                   '有效铁mg/kg', 'pH', imgDataF['编号'], mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx',
+                   'T1')
+            # 锰与ph相关性
+            imgDataMe = nowTable_js.dropna(subset=['有效锰mg/kg', 'pH'])
+            getImg(imgDataMe['有效锰mg/kg'], imgDataMe['pH'], mkdir_path, '有效锰与pH相关性分析图',
+                   '土壤金属指标数据',
+                   '有效锰mg/kg', 'pH', imgDataMe['编号'], mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx',
+                   'W1')
+            # 铜与ph相关性
+            imgDataCu = nowTable_js.dropna(subset=['有效铜mg/kg', 'pH'])
+            getImg(imgDataCu['有效铜mg/kg'], imgDataCu['pH'], mkdir_path, '有效铜与pH相关性分析图',
+                   '土壤金属指标数据',
+                   '有效铜mg/kg', 'pH', imgDataCu['编号'], mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx',
+                   'Z1')
+            # 锌与ph相关性
+            imgDataZn = nowTable_js.dropna(subset=['有效锌mg/kg', 'pH'])
+            getImg(imgDataZn['有效锌mg/kg'], imgDataZn['pH'], mkdir_path, '有效锌与pH相关性分析图',
+                   '土壤金属指标数据',
+                   '有效锌mg/kg', 'pH', imgDataZn['编号'], mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx',
+                   'AC1')
+            # 钼与ph相关性
+            imgDataMu = nowTable_js.dropna(subset=['有效钼mg/kg', 'pH'])
+            getImg(imgDataMu['有效钼mg/kg'], imgDataMu['pH'], mkdir_path, '有效钼与pH相关性分析图',
+                   '土壤金属指标数据',
+                   '有效钼mg/kg', 'pH', imgDataMu['编号'], mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx',
+                   'AF1')
+            getStatisticsImg(nowTable_js['有效硅mg/kg'], '有效硅mg/kg', '有效硅',
+                             mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx', mkdir_path, 'B19')
+            getStatisticsImg(nowTable_js['有效铁mg/kg'], '有效铁mg/kg', '有效铁',
+                             mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx', mkdir_path, 'C19')
+            getStatisticsImg(nowTable_js['有效锰mg/kg'], '有效锰mg/kg', '有效锰',
+                             mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx', mkdir_path, 'D19')
+            getStatisticsImg(nowTable_js['有效铜mg/kg'], '有效铜mg/kg', '有效铜',
+                             mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx', mkdir_path, 'E19')
+            getStatisticsImg(nowTable_js['有效锌mg/kg'], '有效锌mg/kg', '有效锌',
+                             mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx', mkdir_path, 'F19')
+            getStatisticsImg(nowTable_js['有效硼mg/kg'], '有效硼mg/kg', '有效硼',
+                             mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx', mkdir_path, 'G19')
+            getStatisticsImg(nowTable_js['有效钼mg/kg'], '有效钼mg/kg', '有效钼',
+                             mkdir_path + '/土壤金属指标数据-' + nowTime + '.xlsx', mkdir_path, 'H19')
+            # 表13 表14
+            with pd.ExcelWriter(mkdir_path + '/土壤污染风险值数据-' + nowTime +'.xlsx', engine='openpyxl') as writer:
+                resData_14_Style.to_excel(writer, index=False, sheet_name='土壤污染风险值数据')
+                resData_13.to_excel(writer,  sheet_name='频度分析')
+            autoColumns(mkdir_path + '/土壤污染风险值数据-' + nowTime +'.xlsx')
+            nowTable_wr = pd.read_excel(mkdir_path + '/土壤污染风险值数据-' + nowTime + '.xlsx',
+                                        sheet_name='土壤污染风险值数据')
+            getStatisticsImg(nowTable_wr['镉mg/kg'], '镉mg/kg', '镉',
+                             mkdir_path + '/土壤污染风险值数据-' + nowTime + '.xlsx', mkdir_path, 'B19')
+            getStatisticsImg(nowTable_wr['汞mg/kg'], '汞mg/kg', '汞',
+                             mkdir_path + '/土壤污染风险值数据-' + nowTime + '.xlsx', mkdir_path, 'C19')
+            getStatisticsImg(nowTable_wr['砷mg/kg'], '砷mg/kg', '砷',
+                             mkdir_path + '/土壤污染风险值数据-' + nowTime + '.xlsx', mkdir_path, 'D19')
+            getStatisticsImg(nowTable_wr['铅mg/kg'], '铅mg/kg', '铅',
+                             mkdir_path + '/土壤污染风险值数据-' + nowTime + '.xlsx', mkdir_path, 'E19')
+            getStatisticsImg(nowTable_wr['铬mg/kg'], '铬mg/kg', '铬',
+                             mkdir_path + '/土壤污染风险值数据-' + nowTime + '.xlsx', mkdir_path, 'F19')
+            getStatisticsImg(nowTable_wr['镍mg/kg'], '镍mg/kg', '镍',
+                             mkdir_path + '/土壤污染风险值数据-' + nowTime + '.xlsx', mkdir_path, 'G19')
+            show_info('保存完成,点击确定开始生成审核报告。')
+            readData = pd.read_excel(changeFileUrl, sheet_name='Sheet1', converters={'原样品编号': str})
+            if checkType == 'HUNDRED_DATA':
+                readData = readData.head(100)
+            dealDataRes = dealData(readData)
+            # 生成审核报告
+            getReport(dealDataRes,changeFileUrl, saveFileUrl, table_1_data, table_3_data, table_5_data,table_8_data,table_10_data,table_12_data,table_14_data)
+            partReport.getphysicsReport(dealDataRes,'物理指标', changeFileUrl, saveFileUrl, table_1_data, table_3_data, table_5_data,table_8_data,table_10_data,table_12_data,table_14_data)
+            partReport.getConventionalNutrientIndicators(dealDataRes,'常规养分指标', changeFileUrl, saveFileUrl, table_1_data, table_3_data, table_5_data,table_8_data,table_10_data,table_12_data,table_14_data)
+            partReport.getChemicalIndicators(dealDataRes,'一般化学性指标', changeFileUrl, saveFileUrl, table_1_data, table_3_data, table_5_data,table_8_data,table_10_data,table_12_data,table_14_data)
+            partReport.getHeavyMetalIndicators(dealDataRes,'重金属指标', changeFileUrl, saveFileUrl, table_1_data, table_3_data, table_5_data,table_8_data,table_10_data,table_12_data,table_14_data)
+            show_info('审核报告已生成!')
+    except Exception as err:
+        print('err', err)
+        show_error('出错了!')
+
+
+def show_info(info):
+    Messagebox.show_info(title='提示:', message=info)
+def show_error(info):
+    Messagebox.show_error(title='错误:', message=info)
+
+def getPass(num):
+    # 获取设备id 获取相应的注册码
+    d = Querybox()
+    c = d.get_string(prompt=f'本程序免费试用100条数据,使用更多请持您的申请码({num})电话联系管理员(19556503305)获取注册码,审核时输入注册码可使用全部功能。', title='输入注册码',
+                     initialvalue=None, parent=None)
+    if getNum() == c: # 输入的注册码正确
+        # 存储标记文件
+        with open('./html/code.txt', 'w') as file:
+            file.write(
+                '7687698709809hjkjlipomuiyoiupoimvgfghuli376d8bf8f8855ad8de997fa5dac1bd24956aef0cbfa0cf8ac04053a7043e3d90248051f6f03f02b20430949504a5556fb112131fc81205768229ffa023831b04')
+        Messagebox.show_info('注册码提交成功,点击开始审核按钮进行审核!')
+    else:
+        Messagebox.show_error('注册码不正确!')
+def main():
+    # 创建一个GUI窗口
+    root = ttk.Window()  # 使用 ttkbootstrap 创建窗口对象
+
+    root.geometry('500x400')
+    root.title("审核软件")
+    root.resizable(False, False)
+    root.iconbitmap("./img/icon.ico")
+    windowX = root.winfo_screenwidth()
+    windowY = root.winfo_screenheight()
+    cen_x = (windowX - 600) / 2
+    cen_y = (windowY - 500) / 2
+    root.geometry('%dx%d+%d+%d' % (600, 500, cen_x, cen_y))
+    numStr = uuid.getnode()
+    # 添加个标签
+    label1 = ttk.Label(root, text="土壤表层数据指标审核软件",font=("Segoe UI", 14), bootstyle=INFO)
+    label1.grid(row=1, column=1, padx=10, pady=10)
+    b1 = ttk.Button(root, text="选择文件", bootstyle=(INFO, OUTLINE),width=50,command=open_file)  # 使用 ttkbootstrap 的组件
+    b1.grid(row=2, column=1, padx=10, pady=10)
+    b2 = ttk.Button(root, text="开始审核", bootstyle= (INFO, OUTLINE),width=50, command=lambda: checkData(changeFileUrl))  # OUTLINE 是指定边框线
+    b2.grid(row=3, column=1, padx=10, pady=10)
+    b3 = ttk.Button(root, text="保 存", bootstyle= SUCCESS,width=50,command=saveFile)  # OUTLINE 是指定边框线
+    b3.grid(row=4, column=1, padx=10, pady=10)
+    b4 = ttk.Button(root, text="获取申请码", bootstyle=SUCCESS, width=50, command=lambda: getPass(numStr))  # OUTLINE 是指定边框线
+    b4.grid(row=5, column=1, padx=10, pady=10)
+    # 插入logo图片
+
+    # image = ttk.PhotoImage(file="./img/logo_2.jpg")
+
+    img = Image.open("./img/logo_2.jpg")
+    new_img = img.resize((50,50))
+    # 将图像转为tkinter可用的PhotoImage格式
+    photo = ImageTk.PhotoImage(new_img)
+
+    # 显示图像
+    # label = ttk.Label(root, image=photo)
+
+    # 创建一个 Label 并添加图片
+    label = ttk.Label(image=photo,width=50)
+    label.grid(row=7, column=1, padx=10, pady=10)
+    # 写入单位名称
+    label2 = ttk.Label(root, text="©2024 合肥环研生态环境科技有限公司 版权所有", bootstyle=SUCCESS)
+    label2.grid(row=8, column=1, padx=10, pady=10)
+    root.grid_columnconfigure(1, weight=1)
+    root.grid_rowconfigure(1, weight=1)
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()
+