123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875 |
- # -- encoding: utf-8 --
- from openai import OpenAI
- import base64
- import httpx
- import json
- from xlsx_functions_impl import execute_function, save_workbook
- from docx_function_impl import save_document, execute_docx_function
- import sys
- import os
- import io
- import docx
- import openpyxl
- # 只在程序开始时设置一次编码
- if hasattr(sys.stdout, 'buffer'):
- sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
- if hasattr(sys.stderr, 'buffer'):
- sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
- # ---- 本地函数定义 ----
- def encode_image(image_path):
- with open(image_path, "rb") as image_file:
- return base64.b64encode(image_file.read()).decode("utf-8")
- def read_test_result(file_path):
- with open(file_path, "r", encoding="utf-8") as file:
- return file.read()
-
- def read_function_json(file_path):
- with open(file_path, "r", encoding="utf-8") as file:
- return json.load(file)
- def generate_report():
- client = OpenAI(
- api_key="sk-BlGqfNYqP1JwAz7TpYJkPpYxCylb8KUb0R6eHndFQeT3BlbkFJSOr91dOESOeYGKXGif2OJyUE-de7EdOvEx9uwLZ84A",
- http_client=httpx.Client(
- proxy="socks5://socksproxy:8uhb9ijn@34.143.134.123:1080"
- )
- )
- test_result = read_test_result("solid.md")
- image_path = "report_table_sample.png"
- image_base64 = encode_image(image_path)
- functions = read_function_json("docx_functions.json")
- userPrompt = f"""我需要将一份检测结果生成检测报告,以docx的形式输出,目标报告的表格如提供的图片所示,
- 检测数据如下:
- {test_result}
- 请根据检测数据,生成一份检测报告,并按照图片所示的格式输出。
- 你可以操作python-docx生产docx文件,你可以进行多轮操作实现你的目标,如执行完操作后还有后续操作,请回复:'尚未完成',如执行完成,请回复'已完成'。
- """
- messages = [
- {"role": "user", "content": [
- {"type": "text", "text": userPrompt},
- {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image_base64}"}}
- ]}
- ]
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- while True:
- if message.content and "已完成" in message.content:
- break
- if message.function_call:
- name = message.function_call.name
- args = json.loads(message.function_call.arguments)
- result = execute_function(name, **args)
- messages.append({
- "role": "function",
- "name": name,
- "content": result
- })
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- else:
- break
-
- # 保存docx文件
- docx_path = "target_report.docx"
- save_workbook(docx_path)
- print(f"报告已保存到 {docx_path}")
- def print_progress(message):
- """打印进度信息并立即刷新输出缓冲区,确保 UTF-8 编码"""
- if isinstance(message, dict) or isinstance(message, list):
- # 如果是字典或列表,转换为格式化的 JSON 字符串
- import json
- message = json.dumps(message, ensure_ascii=False, indent=2)
-
- # 确保消息是字符串
- if not isinstance(message, str):
- message = str(message)
-
- # 输出消息并刷新缓冲区
- print(message, flush=True)
- def read_confirmation_docx(file_path):
- docx_path = os.path.join(os.path.dirname(__file__), file_path)
- doc = docx.Document(docx_path)
- content = ""
- for paragraph in doc.paragraphs:
- content += paragraph.text
-
- for table in doc.tables:
- for row in table.rows:
- for cell in row.cells:
- content += cell.text
- content += " | "
- content += "\n"
- return content
- def read_test_xlsx(file_path):
- workbook = openpyxl.load_workbook(file_path, data_only=True)
- sheets = workbook.sheetnames
- content = []
- for sheet in sheets:
- sheet = workbook[sheet]
- sheet_content = f"sheet: {sheet}\n"
- for row in sheet.iter_rows(values_only=True):
- row_content = ""
- # 读取cell的值而不是公式
- for cell in row:
- row_content += str(cell) + " | "
- # 判断row_content是否值都为None
- if all(cell is None for cell in row):
- continue
- else:
- sheet_content += row_content + "\n"
- content.append(sheet_content)
- return content
- def extract_test_result(content):
- client = OpenAI(
- # api_key="sk-BlGqfNYqP1JwAz7TpYJkPpYxCylb8KUb0R6eHndFQeT3BlbkFJSOr91dOESOeYGKXGif2OJyUE-de7EdOvEx9uwLZ84A",
- # api_key="AIzaSyBL7YV2mfYjlM97pkn3_lKdlvniXnWkcno",
- # base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
- # http_client=httpx.Client(
- # proxy="socks5://socksproxy:8uhb9ijn@34.143.134.123:1080"
- # )
- api_key="sk-90fa152386b849e29737c6c2812de7d3",
- base_url="https://api.deepseek.com"
- )
- base_prompt = f"""
- 你是一名环境检测领域专家,你需要从环境检测化验单中读取检测结果。
- 你所需要读取的内容是环境检测化验单内容,里面可能包含污水、废气、噪声、土壤、固废等各种检测项目,涉及到各类检测方法,如化学滴定法、色谱法等等。
- 检测报告单已经读取为文本,包含了表单名称以及表单内容。
- 文本内容如下:
- {content}
- 文本行与行之间以换行符分隔,单元格与单元格之间以|分隔。
- 你需要先理解表单格式,再进行有效信息提取。
- 对于污水检测,通常会对一个采样点进行多次采样,然后对每一份样品进行检测。对于检测结果,你需要重点关注以下几个字段(字段名不一定完全一致,你需要有自己的判断):
- 1. 测点编号
- 2. 样品编号
- 3. 样品浓度
- 4. 样品浓度平均值 (平均值或最大值大多数情况下都可以从表单中找到,不需要自己计算,如果表单中没有平均值,则取最大值)
- 5. 采样点标干流量(标干流量只有固定排放源废气才会有,对于无组织废气则不存在标干流量)
- 这些字段所对应的值需要体现在检测结果报告中。
- """
- prompt = base_prompt + """
- 以JSON格式返回数据,返回格式如下:
- {
- "sheet_name": "sheet_name",
- "test_item": "检测项目(检测项目有时候并不在表单内容模块而在表单标题里,需要你自己判断)",
- "sampling_date": "采样日期",
- "sample_type": "样品类型",
- "test_method": "检测方法",
- "test_threshold": "检出限",
- "test_instrument": "检测仪器",
- "test_result": [
- {
- "sampling_point_code": "采样点编号",
- "test_detail": [
- {
- "sample_code": "样品编号",
- "test_item": "检测项目",
- "test_value": "检测值",
- "test_unit": "检测单位"
- }
- ], //for test_item in test_items
- "avg_or_max_value": "检出平均值或最大值",
- "standard_dry_flow": "标干流量",
- "flow_unit": "标干流量单位",
- "emission_rate": "排放速率",
- "emission_unit": "速率单位"
- }
- ] //for sampling_point_code in sampling_point_codes
- }
- 生成json时请确保检测单中所有数据都写到json中,不要有任何遗漏,因为这是一份检测报告,数据完整性非常重要。不要因为返回的json长度过长而进行省略。
- """
- messages = [
- {"role": "user", "content": prompt}
- ]
- response = client.chat.completions.create(
- model="deepseek-chat",
- messages=messages,
- )
- print(response.choices[0].message.content)
- # 将json格式化
- try:
- json_content = json.loads(response.choices[0].message.content)
- return json_content
- except:
- start_index = response.choices[0].message.content.find("{")
- end_index = response.choices[0].message.content.rfind("}") + 1
- json_content = json.loads(response.choices[0].message.content[start_index:end_index])
- return json_content
-
- def extract_sampling_point_info(content):
- client = OpenAI(
- # api_key="sk-BlGqfNYqP1JwAz7TpYJkPpYxCylb8KUb0R6eHndFQeT3BlbkFJSOr91dOESOeYGKXGif2OJyUE-de7EdOvEx9uwLZ84A",
- # # api_key="AIzaSyBL7YV2mfYjlM97pkn3_lKdlvniXnWkcno",
- # # base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
- # http_client=httpx.Client(
- # proxy="socks5://socksproxy:8uhb9ijn@34.143.134.123:1080"
- # )
- api_key="sk-90fa152386b849e29737c6c2812de7d3",
- base_url="https://api.deepseek.com"
- )
- base_prompt = f"""
- 你是一名环境检测领域专家,现在我有一份环境检测现场采样确认单,你需要从这份确认单中提取采样日期、采样点编号、采样点名称、检测项目信息。
- 确认单内容如下:
- {content}
- 确认单已经读取为文本,表格单元格以|分隔,表格行与行以换行符分隔。
- 合并单元格,如A1与A2合并后,那么内容里A1与A2的值是一样的,当你发现几个单元格值都是一样的时候,代表这几个单元格是合并的。
- 你需要先理解表单格式,然后再提取相应数据。
- 以JSON格式返回数据,返回格式如下:
- """
- prompt = base_prompt + """
- {
- "sampling_date": "采样日期",
- "sampling_info": [
- {
- "sampling_point_code": "采样点编号",
- "sampling_point": "采样点名称",
- "test_item": "检测项目信息"
- } //for sampling_point_code in sampling_point_codes
- ]
- }
- """
- messages = [
- {"role": "user", "content": prompt}
- ]
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- )
- try:
- json_content = json.loads(response.choices[0].message.content)
- return json_content
- except:
- start_index = response.choices[0].message.content.find("{")
- end_index = response.choices[0].message.content.rfind("}") + 1
- json_content = json.loads(response.choices[0].message.content[start_index:end_index])
- return json_content
- def extract_sampling_scheme(content):
- client = OpenAI(
- # api_key="sk-BlGqfNYqP1JwAz7TpYJkPpYxCylb8KUb0R6eHndFQeT3BlbkFJSOr91dOESOeYGKXGif2OJyUE-de7EdOvEx9uwLZ84A",
- # # api_key="AIzaSyBL7YV2mfYjlM97pkn3_lKdlvniXnWkcno",
- # # base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
- # http_client=httpx.Client(
- # proxy="socks5://socksproxy:8uhb9ijn@34.143.134.123:1080"
- # )
- api_key="sk-90fa152386b849e29737c6c2812de7d3",
- base_url="https://api.deepseek.com"
- )
- base_prompt = f"""
- 你是一名环境检测领域专家,现在我有一份环境检测现场采样方案,你需要从这份方案中提取监测类别、采样点编号、监测点位、监测频次、监测项目信息。
- 方案内容如下:
- {content}
- 方案已经读取为文本,表格单元格以|分隔,表格行与行以换行符分隔。
- 合并单元格,如A1与A2合并后,那么内容里A1与A2的值是一样的,当你发现几个单元格值都是一样的时候,代表这几个单元格是合并的。
- 你需要先理解表单格式,然后再提取相应数据。
- 以JSON格式返回数据,返回格式如下:
- """
- prompt = base_prompt + """
- [
- {
- "monitoring_category": "监测类别",
- "sampling_info": [
- {
- "sampling_point_code": "采样点编号",
- "sampling_point": "监测点位",
- "sampling_frequency": "监测频次",
- "test_item": "检测项目信息"
- }
- ] //for sampling_point_code in sampling_point_codes
- }
- ]
- """
- messages = [
- {"role": "user", "content": prompt}
- ]
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- )
- try:
- json_content = json.loads(response.choices[0].message.content)
- return json_content
- except:
- start_index = response.choices[0].message.content.find("{")
- end_index = response.choices[0].message.content.rfind("}") + 1
- json_content = json.loads(response.choices[0].message.content[start_index:end_index])
- return json_content
- def llm_operating_docx(prompt):
- client = OpenAI(
- api_key="sk-BlGqfNYqP1JwAz7TpYJkPpYxCylb8KUb0R6eHndFQeT3BlbkFJSOr91dOESOeYGKXGif2OJyUE-de7EdOvEx9uwLZ84A",
- # api_key="AIzaSyBL7YV2mfYjlM97pkn3_lKdlvniXnWkcno",
- # base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
- http_client=httpx.Client(
- proxy="socks5://socksproxy:8uhb9ijn@34.143.134.123:1080"
- )
- )
- # image_path = os.path.join(os.path.dirname(__file__), "table_template.png")
- # image_url = encode_image(image_path)
- docx_functions = read_function_json(os.path.join(os.path.dirname(__file__), "docx_functions.json"))
- image_path = os.path.join(os.path.dirname(__file__), "table_template.png")
- waste_water_image_url = encode_image(image_path)
- gas_image_path = os.path.join(os.path.dirname(__file__), "gas.png")
- gas_image_url = encode_image(gas_image_path)
- gas_free_image_path = os.path.join(os.path.dirname(__file__), "gas_free.png")
- gas_free_image_url = encode_image(gas_free_image_path)
- noise_image_path = os.path.join(os.path.dirname(__file__), "noise.png")
- noise_image_url = encode_image(noise_image_path)
- messages = [
- {"role": "user", "content": prompt}
- ]
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=docx_functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- while True:
- if message.content and "已完成" in message.content:
- print(message.content)
- break
- if message.function_call:
- name = message.function_call.name
- args = json.loads(message.function_call.arguments)
- result = execute_docx_function(name, **args)
- print(result)
- messages.append({
- "role": "function",
- "name": name,
- "content": json.dumps(result)
- })
- response = client.chat.completions.create(
- model="gpt-4.1-mini",
- messages=messages,
- functions=docx_functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- else:
- messages.append({
- "role": "user",
- "content": "你回复了尚未完成,但并没有返回function call,是遇到什么问题了吗?如果需要继续执行,请继续回复:尚未完成"
- })
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=docx_functions,
- function_call="auto"
- )
- message = response.choices[0].message
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- return "ok"
- def llm_operating_xlsx(prompt):
- client = OpenAI(
- api_key="sk-BlGqfNYqP1JwAz7TpYJkPpYxCylb8KUb0R6eHndFQeT3BlbkFJSOr91dOESOeYGKXGif2OJyUE-de7EdOvEx9uwLZ84A",
- # api_key="AIzaSyBL7YV2mfYjlM97pkn3_lKdlvniXnWkcno",
- # base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
- http_client=httpx.Client(
- proxy="socks5://socksproxy:8uhb9ijn@34.143.134.123:1080"
- )
- )
- image_path = os.path.join(os.path.dirname(__file__), "tpl.png")
- image_url = encode_image(image_path)
- xlsx_functions = read_function_json(os.path.join(os.path.dirname(__file__), "xlsx_functions.json"))
- messages = [
- {"role": "user", "content": [
- {"type": "text", "text": prompt},
- {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image_url}"}},
- ]}
- ]
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=xlsx_functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print(message.content)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- while True:
- if message.content and "已完成" in message.content:
- print(message.content)
- messages.append({
- "role": "assistant",
- "content": message.content,
- })
- break
- if message.function_call:
- name = message.function_call.name
- args = json.loads(message.function_call.arguments)
- result = execute_function(name, **args)
- print(result)
- messages.append({
- "role": "function",
- "name": name,
- "content": json.dumps(result)
- })
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=xlsx_functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print(message.content)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- else:
- messages.append({
- "role": "user",
- "content": "你回复了尚未完成,但并没有返回function call,是遇到什么问题了吗?如果需要继续执行,请继续回复:尚未完成"
- })
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=xlsx_functions,
- function_call="auto"
- )
- message = response.choices[0].message
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- return messages
- def let_llm_read_excel(file_path, output_path, file_type):
- client = OpenAI(
- api_key="sk-BlGqfNYqP1JwAz7TpYJkPpYxCylb8KUb0R6eHndFQeT3BlbkFJSOr91dOESOeYGKXGif2OJyUE-de7EdOvEx9uwLZ84A",
- # api_key="AIzaSyBL7YV2mfYjlM97pkn3_lKdlvniXnWkcno",
- # base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
- http_client=httpx.Client(
- proxy="socks5://socksproxy:8uhb9ijn@34.143.134.123:1080"
- )
- )
- # deepseek api
- # client = OpenAI(
- # api_key="sk-90fa152386b849e29737c6c2812de7d3",
- # base_url="https://api.deepseek.com"
- # )
- # json路径替换为全局路径
- functions = read_function_json(os.path.join(os.path.dirname(__file__), "xlsx_functions.json"))
- # Break down the nested f-string into separate parts
- base_prompt = f"""
- 你是一名环境检测领域专家,你可以读取excel的内容以及相关格式从而对excel内容有全面的理解。
- 你所需要读取的excel内容是环境检测化验单内容,里面可能包含污水、废气、噪声、土壤、固废等各种检测项目,涉及到各类检测方法,如化学滴定法、色谱法等等。
- 现在有一些检测化验单需要你读取并理解其中内容,你可以操作openpyxl读取excel内容。
- 对于污水检测,通常会对一个采样点进行多次采样,然后对每一份样品进行检测。对于检测结果,你需要重点关注以下几个字段:
- 1. 测点编号
- 2. 样品编号
- 3. 样品浓度
- 4. 样品浓度平均值
- 5. 采样点标干流量(标干流量只有固定排放源废气才会有,对于无组织废气则不存在标干流量)
- 这些字段所对应的值需要体现在检测结果报告中。
- 需要读取并理解的excel文件路径是:{file_path}。
- 读取excel时保证把sheet内有数据区域全部读取到,不要有遗漏的数据区域。
- 读取时先调用load_workbook方法加载工作表再执行后续操作。
- 如果excel存在多个sheet,全部读取。
- 如果你觉得你已经理解了文件内容,请回复:'已完成'。如果你觉得还需要更多信息,请回复:'尚未完成'。
- """
- excel_data = []
- messages = [
- {"role": "user", "content": base_prompt}
- ]
- print_progress("开始读取excel内容...")
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print_progress(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- while True:
- if message.content and "已完成" in message.content:
- print_progress("读取完成")
- print_progress(message.content)
- prompt = """你已完成读取,请将excel内容转化为JSON格式返回,JSON格式如下:
- [
- {
- "sheet_name": "sheet_name",
- "sheet_data": [
- {
- "test_item": "检测项目",
- "sampling_date": "采样日期",
- "sample_type": "样品类型",
- "sampling_point_code": "采样点编号",
- "sampling_point": "采样点",
- "avg_value": "检出平均值",
- "test_result": [
- {
- "sample_code": "样品编号",
- "test_value": "样品检出值",
- "test_unit": "测试单位",
- "standart_dry_flow": "标干流量",
- "flow_unit": "标干流量单位",
- "emission_rate": "排放速率",
- "emission_unit": "速率单位"
- }
- ] //for result in sampling point
- } //for sheet_name in sheet_names
- ]
- }
- ]
- 字段如果在excel内没有读到,可以为空。
- 生成json时请确保检测单中所有数据都写到json中,不要有任何遗漏,因为这是一份检测报告,数据完整性非常重要。不要因为返回的json长度过长而进行省略。
- """
- messages.append({
- "role": "user",
- "content": prompt
- })
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=functions,
- function_call="auto"
- )
- message = response.choices[0].message
- try:
- json_result = json.loads(message.content)
- print_progress(json_result)
- with open(os.path.join(os.path.dirname(__file__), "data2.json"), "w", encoding="utf-8") as f:
- json.dump(json_result, f, ensure_ascii=False)
- except Exception as e:
- # 手动解析json
- start_index = message.content.find("[")
- end_index = message.content.rfind("]") + 1
- json_result = json.loads(message.content[start_index:end_index])
- print_progress(json_result)
- with open(os.path.join(os.path.dirname(__file__), "data2.json"), "w", encoding="utf-8") as f:
- json.dump(json_result, f, ensure_ascii=False)
-
- excel_data = message.content
- messages.append({
- "role": "assistant",
- "content": message.content,
- })
- break
- if message.function_call:
- name = message.function_call.name
- args = json.loads(message.function_call.arguments)
- result = execute_function(name, **args)
- print_progress(result)
- messages.append({
- "role": "function",
- "name": name,
- "content": json.dumps(result)
- })
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print_progress(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- else:
- break
- print_progress("读取完成")
- # print_progress(excel_data)
- # prompt = f"""
- # 你已经完整读取了excel内容,请根据你的理解对这份检测单做一份完整总结
- # """
- # messages.append({
- # "role": "user",
- # "content": prompt
- # })
- # response = client.chat.completions.create(
- # model="gpt-4.1",
- # messages=messages,
- # functions=functions,
- # function_call="auto"
- # )
- # message = response.choices[0].message.content
- # print(message)
- image_path = os.path.join(os.path.dirname(__file__), "table_template.png")
- image_base64 = encode_image(image_path)
- tpl_path = os.path.join(os.path.dirname(__file__), "report_tpl.xlsx")
- # output_path = "report_222.xlsx"
- messages.clear()
- # Break down the second nested f-string
- # report_prompt = f"""你已经完整读取了excel内容,请根据检测单内容JSON,填写excel最终检测报告单,
- # 检测报告单模板路径:{tpl_path}
- # 报告模板中包含多个sheet,每个sheet对应不同的检测项目,请根据读取的内容选择合适的报告模板sheet并填写内容。
- # 在填写检测报告时,请先读取excel的表头,根据表头名称从上一环节读取的检测单内容中选择正确的检测项目,然后填写检测报告。
- # 检测报告单模板的excel表格行数或列数可能不够,你需要根据检测单内容自主决定是否需要添加行列。
- # 你可以操作openpyxl操作excel文件,
- # 你可以进行多轮操作实现你的目标,
- # 最终内容填写完成后,将excel文件另存为:{output_path}
- # 如执行完操作后还有后续操作,请回复:'尚未完成',如执行完成,请回复'已完成'。
- # """
- report_prompt = f"""
- 你是一名环境检测报告生成专家,熟悉环境检测报告的生成流程及报告典型要素。我现在有一份json格式的环境检测单数据,需要你根据这份数据生成一份检测报告,
- 数据如下:
- {excel_data}
- 对于检测结果,你需要重点关注以下几个字段:
- 1. 测点编号 json中的sheet_data.sampling_point_code
- 2. 样品编号 json中的sheet_data.test_result.sample_code
- 3. 样品浓度 json中的sheet_data.test_result.test_value
- 4. 样品浓度平均值 json中的sheet_data.avg_value
- 检测报告是以表格作为检测结果的展示方式,你可以参考图片所示的检测模板。
- 通常对于废水检测报告,检测报告单重点字段如下:
- 1.测点编号
- 2.测点名称
- 3.检测项目名称
- 4.检测项目单位
- 5.多轮检测值(如:第一次、第二次、第三次)
- 6.检测平均值或最大值
- 7.参考限值
- 对于废气检测报告,存在两种形式的废气:
- 1. 固定排放源废气
- 2. 无组织废气
- 对于固定排放源废气,检测报告单重点字段如下:
- 1.测点编号
- 2.测点名称
- 3.检测项目名称(如果是固定源废气,检测项目内需要包含一项:标杆流量)
- 4.检测项目单位
- 5.多轮检测值(如:第一次、第二次、第三次)
- 6.检测平均值
- 7.参考限值
- 对于无组织废气,检测报告单重点字段如下:
- 1.测点编号
- 2.测点名称
- 3.检测项目名称
- 4.检测项目单位
- 5.多轮检测值(如:第一次、第二次、第三次)
- 6.检测最大值
- 7.参考限值
- 请根据检测单内容JSON,基于报告模板xlsx文件填写最终检测报告单,
- 检测报告单模板路径:{tpl_path}
- 报告模板中包含多个sheet,每个sheet对应不同的检测项目,请根据读取的内容选择合适的报告模板sheet并填写内容。
- 在填写检测报告时,请先读取xlsx模板的整体结构,从而在填写时可以把内容填写到正确位置。
- 检测报告单模板的excel表格行数或列数可能不够,你需要根据检测单内容自主决定是否需要添加行列。
- 检测报告单模板里可能包含合并单元格,请根据合并单元格的样式来填写内容。
- 你可以操作openpyxl操作xlsx文件,
- 图片是一份报告单表格的截图,你可以作为样式参考来生成你的报告表格。
- 最终内容填写完成后,将xlsx文件另存为:{output_path}
- 如执行完操作后还有后续操作,请回复:'尚未完成',如执行完成,请回复'已完成'。
- """
- messages.append(
- {"role": "user", "content": [
- {"type": "text", "text": report_prompt},
- {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image_base64}"}}
- ]}
- )
- docx_functions = read_function_json(os.path.join(os.path.dirname(__file__), "docx_functions.json"))
- print_progress("开始生成检测报告...")
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print_progress(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- while True:
- if message.content and "已完成" in message.content:
- print_progress("检测报告生成完成")
- break
- if message.function_call:
- name = message.function_call.name
- args = json.loads(message.function_call.arguments)
- result = execute_function(name, **args)
- print_progress(result)
- messages.append({
- "role": "function",
- "name": name,
- "content": json.dumps(result)
- })
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print_progress(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
- else:
- messages.append({
- "role": "user",
- "content": "你回复了尚未完成,但并没有返回function call,是遇到什么问题了吗?如果需要继续执行,请继续回复:尚未完成"
- })
- response = client.chat.completions.create(
- model="gpt-4.1",
- messages=messages,
- functions=functions,
- function_call="auto"
- )
- message = response.choices[0].message
- print(message)
- messages.append({
- "role": "assistant",
- "content": message.content,
- "function_call": message.function_call
- })
-
- # 保存docx文件
- # docx_path = "report_ds.docx"
- # save_document(docx_path)
- # print(f"报告已保存到 {docx_path}")
- if __name__ == "__main__":
- # args = sys.argv
- # let_llm_read_excel(args[1], args[2], args[3])
- # content = read_confirmation_docx("file/scheme.docx")
- # confirmation_content_raw = read_confirmation_docx("file/confirm.docx")
- # print('采样确认单读取完成')
- # confirmation_content = extract_sampling_point_info(confirmation_content_raw)
- # print('采样确认单提取完成')
- # scheme_content_raw = read_confirmation_docx("file/scheme.docx")
- # print('采样方案读取完成')
- # scheme_content = extract_sampling_scheme(scheme_content_raw)
- # print('采样方案提取完成')
- # extract_sampling_scheme(content)
- # test_content = []
- # content = read_test_xlsx("file/cod.xlsx")
- # print('检测结果读取完成')
- # for sheet in content:
- # test_content.append(extract_test_result(sheet))
- # print('检测结果提取完成')
- # print(test_content)
- # output_path = "report_zzz.xlsx"
- # xlsx_tpl_path = os.path.join(os.path.dirname(__file__), "report_tpl.xlsx")
- # prompt = f"""
- # 你是一名环境检测报告生成专家,熟悉环境检测报告的生成流程及报告典型要素,具有环境检测行业深厚的背景知识。
- # 我现在有一套环保检测数据,需要你根据这几份数据生成一份检测报告,
- # 数据如下:
- # 采样确认单:{confirmation_content}
- # 采样方案:{scheme_content}
- # 检测结果:{test_content}
- # 数据里的字段含义如下:
- # 1.sampling_point_code:测点编号
- # 2.sampling_point:测点名称
- # 3.test_item:检测项目名称
- # 4.test_value:检测结果
- # 5.test_unit:检测单位
- # 6.sampling_date:采样日期
- # 7.sample_type:样品类型
- # 8.test_detail:检测结果
- # 9.emission_unit:速率单位
- # 10.standart_dry_flow:标干流量
- # 11.flow_unit:标干流量单位
- # 12.emission_rate:排放速率
- # 13.emission_unit:速率单位
- # 14.avg_value:检测平均值
- # 15.test_method:检测方法
- # 16.test_threshold:检出限
- # 17.test_instrument:检测仪器
- # 请根据检测结果数据填写最终报告表单,以下字段为填写时重点内容,不可遗漏:
- # 1、测点编号
- # 2、测点名称
- # 3、项目名称
- # 4、单位
- # 5、检测结果(检测结果可能包含多轮检测值,如:第一次、第二次、第三次、均值或最大值,需要根据检测结果的实际情况来填写)
- # 6、参考限值
- # 你需要把检测结果的数据完整填写到报告表单里。
- # 图片是一张污水检测结果报告单的截图,你可以参考图片的表格样式,但注意最终报告数据需要根据实际检测结果来填写,不要把参考图片里的数据填写到报告表格里。
- # 你可以使用openpyxl操作xlsx文件,现有一份报告单模板xlsx文件,路径为:{xlsx_tpl_path},文件里已经设置好表格样式,只需要把相应的数据填到正确的位置即可。
- # 模板xlsx里包含多个sheet,每个sheet对应不通的检测类型,如污水、噪音、废气等,你需要根据检测结果选择合适的sheet填写内容,
- # 选择sheet后,先完整读取模板结构,然后再根据模板结构填写数据内容,请注意表格中可能会有合并单元格,遇到合并单元格格式时请正确理解合并单元格含义再进行数据填写。
- # 如果模板的行列不够填写数据,请自行添加行列,但添加行列时注意保持表格的样式,
- # 内容填写完成后,请将xlsx文件另存为:{output_path}。
- # 你可以进行多轮操作来进行报告表单填写,如果还有后续操作,请回复:'尚未完成',如果已经填写完成,请回复:'已完成'。
- # """
- # llm_operating_xlsx(prompt)
- print('heelo')
|