1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867 |
- 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
- import copy
- 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
- from docx.enum.section import WD_ORIENTATION
- 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({})
- # 保存一份原始数据 数据修约时使用
- originData = 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)
- 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()
- median_value = arr.median() # 中位数
- jc_value = arr.max() - arr.min() # 极差
- 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)
- 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})
- 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=['原样品编号'])
- global originData
- originData = pd.read_excel(fileUrl, dtype='str')
- 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')
- strList = ['原样品编号','样品编号','地理位置','土壤类型','母质','土地利用类型','土壤质地']
- for i in simpleData.columns:
- if i not in strList:
- simpleData[i] = pd.to_numeric(simpleData[i], errors='coerce')
- # 处理重复样品
- #res = getRepeat(simpleData)
- #simpleData = simpleData._append(res).drop_duplicates(subset=['原样品编号'], keep='last')
- 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['母质'],
- '土壤质地': 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['原样品编号'],
- # '样品编号': simpleData['样品编号'],
- # '土地利用类型': resData['土地利用类型'],
- # '指标': table_1_res['异常指标'],
- # '原因': table_1_res['审核结果']
- # })
- table_1_index['原样品编号'] = resData['编号']
- table_1_index['样品编号'] = resData['样品编号']
- table_1_index['土地利用类型'] = resData['土地利用类型']
- table_1_index['指标'] = table_1_res['异常指标']
- table_1_index['原因'] = 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
- resData_2 = frequency_analysis(data_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['审核结果']
- # })
- # table_3_index['样品编号'] = simpleData['样品编号']
- table_3_index['指标'] = res_3_v['异常指标']
- table_3_index['原因'] = res_3_v['审核结果']
- resData_3_Style = resData_3.style.apply(highlight_condition, axis=1)
- # 表4--------------------------表4 水稳性大团聚体频度分析-----------------------
- 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)
- # 表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['阳离子交换量'] # 交换性盐基/阳离子交换量
- })
- resData_5 = resData_5.reset_index(drop=True)
- res_5_v = pb.cation_value(resData_5)
- resData_5['审核结果'] = res_5_v['审核结果']
- global resData_5_Style
- global table_5_data
- table_5_data = resData_5
- # 提取异常数据
- global table_5_index
- # table_5_index = pd.DataFrame({
- # '样品编号': simpleData['样品编号'],
- # '指标': res_5_v['异常指标'],
- # '原因': res_5_v['审核结果']
- # })
- # table_5_index['样品编号'] = simpleData['样品编号']
- table_5_index['指标'] = res_5_v['异常指标']
- table_5_index['原因'] = res_5_v['审核结果']
- resData_5_Style = resData_5.style.apply(highlight_condition, axis=1)
- # 表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 * 22.9898 / 100
- changK = kArr * 39.0983 / 100
- changeCa = caArr * 40 / 100
- changeMg = mgArr * 24.305 / 100
- changeCl = clArr * 35.453 / 100
- changeCo = coArr * 60 / 100
- changeCOH = hcoArr * 61.0168 / 100
- changeSo = soArr * 96.06 / 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,
- '(全盐量-水溶性八大离子加和)x2/(全盐量+水溶性八大离子加和)*100': 2*(allArr - eightPlusArr) / (allArr + eightPlusArr) * 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['审核结果']
- # })
- # table_8_index['样品编号'] = simpleData['样品编号']
- table_8_index['指标'] = res_value_8['异常指标']
- table_8_index['原因'] = res_value_8['审核结果']
- resData_8_Style = resData_8.style.apply(highlight_condition, axis=1)
- # 表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['审核结果']
- # 写入表格
- 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['审核结果']
- # })
- # table_10_index['样品编号'] = simpleData['样品编号']
- table_10_index['指标'] = res_value_10['异常指标']
- table_10_index['原因'] = 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['审核结果']
- # })
- # table_12_index['样品编号'] = simpleData['样品编号']
- table_12_index['指标'] = res_value_12['异常指标']
- table_12_index['原因'] = res_value_12['审核结果']
- resData_12_Style = resData_12.style.apply(highlight_condition, axis=1)
- # 写入表格
- # 表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['审核结果']
- # })
- # table_14_index['样品编号'] = simpleData['样品编号']
- table_14_index['指标'] = res_value_14['异常指标']
- table_14_index['原因'] = res_value_14['审核结果']
- resData_14_Style = resData_14.style.apply(highlight_condition, axis=1)
- # 写入表格
- # 表13--------------------------表13 土壤重金属频度分析----------------------------------------
- global resData_13
- resData_13 = frequency_analysis(
- resData_14[['镉mg/kg', '汞mg/kg', '砷mg/kg', '铅mg/kg', '铬mg/kg', '镍mg/kg']])
- show_info('文件审核完成,请点击保存按钮保存文件!')
- else:
- #提示文件为空 重新选择
- print("Excel 文件为空。")
- except Exception as err:
- print('审核过程中出错!', err)
- show_error(f'审核过程中出错!错误原因:{err}')
- 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['土地利用类型'],
- '指标': pd.Series(table_1_index['指标']) + pd.Series(table_3_index['指标']) + pd.Series(table_5_index['指标']) + pd.Series(table_8_index['指标']) + pd.Series(table_10_index['指标']) + pd.Series(table_12_index['指标']) + pd.Series(table_14_index['指标']),
- '原因': pd.Series(table_1_index['原因']) + pd.Series(table_3_index['原因']) + pd.Series(table_5_index['原因']) + pd.Series(table_8_index['原因']) + pd.Series(table_10_index['原因']) + pd.Series(table_12_index['原因']) + pd.Series(table_14_index['原因']),
- '结合外业调查及相关信息评价': emptyArr,
- '数据判定': emptyArr
- })
- newData = newData.replace(np.nan, '')
- print('newData----', newData)
- name = os.path.basename(changeFileUrl)
- n = name.split('.')
- areaName = n[0].replace('数据', '')
- # 新建文档
- doc = Document()
- # 获取文档的第一个节(默认新建文档只有一个节)
- section = doc.sections[0]
- # 设置页面方向为横向
- new_width, new_height = section.page_height, section.page_width
- section.orientation = WD_ORIENTATION.LANDSCAPE
- section.page_width = new_width
- section.page_height = new_height
- # 添加标题
- 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*')
- )
- # 指定文件路径
- file_path = 'config/fileurl.txt' # 修改为你的文件路径
- # 读取整个文件内容
- with open(file_path, 'r', encoding='utf-8') as file:
- content = file.read()
- filename = filedialog.askopenfilename(
- title='选择文件',
- initialdir=content, # D:/实验室/16、三普
- filetypes=filetypes)
- # 提取目录部分
- directory_path = os.path.dirname(filename)
- # 打开文件并写入内容
- with open(file_path, 'w', encoding='utf-8') as file:
- file.write(directory_path)
- # 这里增加判断 若文件为空提示错误
- 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(originData,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(originData, 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)
- # 新建一个文档
- 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:
- 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)
- 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='coerce')
- # 处理重复样品
- #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(originData,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(originData,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(originData,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(originData,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(originData,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()
|