DinaFatikh commited on
Commit
11cdbcb
·
verified ·
1 Parent(s): 2ec2251

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -33
app.py CHANGED
@@ -7,6 +7,8 @@ from io import BytesIO
7
  import tempfile
8
  import os
9
  from PIL import Image
 
 
10
 
11
  # Функция для обработки PDF и извлечения данных
12
  def process_pdf(file):
@@ -65,7 +67,7 @@ def process_pdf(file):
65
 
66
  # Сохраняем данные в список с обновленными названиями столбцов
67
  data_list.append({
68
- '№ локальной сметы': estimate_number,
69
  'Наименование': estimate_name,
70
  'Рабочие': labor_cost,
71
  'Техника': machine_cost,
@@ -82,12 +84,9 @@ def process_pdf(file):
82
  # Преобразуем список данных в DataFrame
83
  df = pd.DataFrame(data_list)
84
 
85
- # Убираем лишние пробелы и символы из названий столбцов
86
- df.columns = df.columns.str.strip()
87
-
88
  # Рассчитываем общую сумму по всем сметам для каждой категории
89
  total_row = pd.DataFrame({
90
- '№ локальной сметы': ['Итого'],
91
  'Наименование': [''],
92
  'Рабочие': [df['Рабочие'].sum()],
93
  'Техника': [df['Техника'].sum()],
@@ -102,7 +101,7 @@ def process_pdf(file):
102
 
103
  # Создаем таблицу с процентным соотношением, округленным до двух знаков после запятой
104
  total_sum = df['ВСЕГО ПО СМЕТЕ'].iloc[:-1].sum() # исключаем строку "Итого"
105
- df_percentage = df[['№ локальной сметы', 'Наименование']].copy()
106
  df_percentage['Процент от общей суммы'] = ((df['ВСЕГО ПО СМЕТЕ'].iloc[:-1] / total_sum) * 100).round(2)
107
 
108
  # Создание круговой диаграммы
@@ -142,12 +141,44 @@ def process_pdf(file):
142
  detailed_report_path = os.path.join(temp_dir, "detailed_report.xlsx")
143
  percentage_report_path = os.path.join(temp_dir, "percentage_report.xlsx")
144
 
145
- df.to_excel(detailed_report_path, index=False)
 
146
  df_percentage.to_excel(percentage_report_path, index=False)
147
 
148
  # Возвращаем пути к файлам и диаграмму
149
  return df, df_percentage, pie_chart, detailed_report_path, percentage_report_path
150
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  # CSS для блокировки копирования текста
152
  custom_css = """
153
  * {
@@ -158,46 +189,30 @@ custom_css = """
158
  }
159
  """
160
 
161
- # Создаем интерфейс Gradio с блоками и адаптивным дизайном
162
  with gr.Blocks(css=custom_css) as demo:
163
- # Основной заголовок и подзаголовок
164
  with gr.Row():
165
- gr.Markdown("### **AIGineer | ИИ УПРАВЛЕНИЕ СТРОИТЕЛЬСТВОМ**", elem_id="header")
166
- gr.Markdown("**На текущий момент система считает сметы в ценах от 2023**", elem_id="subheader")
167
 
168
- # Загрузка файла (текст выравнивается по центру)
169
  with gr.Row():
170
- upload_button = gr.File(label="ЗАГРУЗИТЕ СМЕТУ В PDF", elem_id="upload")
171
 
172
- # Первая таблица с заголовком и описанием
173
- with gr.Row():
174
- gr.Markdown("<br>") # Добавляем расстояние перед таблицей
175
- with gr.Row():
176
- gr.Markdown("<h3 style='text-align: center;'>ДЕТАЛИЗИРОВАННЫЙ БЮДЖЕТ</h3>", elem_id="title1")
177
  with gr.Row():
178
- gr.Markdown("Отчет дает полное представление о том, как распределяются средства по каждому разделу сметной документации. Он разбивает затраты на ключевые категории — оплата труда, техника, материалы, логистика и оборудование. Это позволяет держать под контролем каждую статью расходов и моментально видеть, где происходят основные затраты.", elem_id="desc1")
179
  with gr.Row():
180
- output_table_1 = gr.Dataframe(headers=["№ локальной сметы", "Наименование", "Рабочие", "Техника", "Материалы", "Перевозки", "Оборудование", "ВСЕГО ПО СМЕТЕ"], elem_id="table1")
181
 
182
- # Расстояние между таблицами
183
- with gr.Row():
184
- gr.Markdown("<br>") # Добавляем расстояние между таблицами
185
-
186
- # Вторая таблица с заголовком и описанием
187
- with gr.Row():
188
- gr.Markdown("<h3 style='text-align: center;'>ПРОЦЕНТНОЕ РАСПРЕДЕЛЕНИЕ ЛОКАЛЬНЫХ СМЕТ</h3>", elem_id="title2")
189
  with gr.Row():
190
- gr.Markdown("Важный инструмент для стратегического планирования, который помогает легко сравнивать между собой разделы проекта, понимая, какие из них требуют большего финансирования, а какие — меньшего. Это позволяет эффективно распределять ресурсы и достигать максимальной отдачи.", elem_id="desc2")
191
  with gr.Row():
192
- output_table_2 = gr.Dataframe(headers=["№ локальной сметы", "Наименование", "Процент от общей суммы"], elem_id="table2")
193
 
194
- # Третья таблица с диаграммой
195
  with gr.Row():
196
- gr.Markdown("<h3 style='text-align: center;'>СТРУКТУРА РАСХОДОВ ПО КАТЕГОРИЯМ</h3>", elem_id="title3")
197
  with gr.Row():
198
- output_plot = gr.Image(type="pil", elem_id="plot")
199
 
200
- # Кнопки для скачивания Excel-файлов
201
  with gr.Row():
202
  download_excel_1 = gr.File(label="Скачать детализированный отчет")
203
  download_excel_2 = gr.File(label="Скачать процентное соотношение")
 
7
  import tempfile
8
  import os
9
  from PIL import Image
10
+ import openpyxl
11
+ from openpyxl.styles import Font, PatternFill
12
 
13
  # Функция для обработки PDF и извлечения данных
14
  def process_pdf(file):
 
67
 
68
  # Сохраняем данные в список с обновленными названиями столбцов
69
  data_list.append({
70
+ '№ сметы': estimate_number,
71
  'Наименование': estimate_name,
72
  'Рабочие': labor_cost,
73
  'Техника': machine_cost,
 
84
  # Преобразуем список данных в DataFrame
85
  df = pd.DataFrame(data_list)
86
 
 
 
 
87
  # Рассчитываем общую сумму по всем сметам для каждой категории
88
  total_row = pd.DataFrame({
89
+ '№ сметы': ['Итого'],
90
  'Наименование': [''],
91
  'Рабочие': [df['Рабочие'].sum()],
92
  'Техника': [df['Техника'].sum()],
 
101
 
102
  # Создаем таблицу с процентным соотношением, округленным до двух знаков после запятой
103
  total_sum = df['ВСЕГО ПО СМЕТЕ'].iloc[:-1].sum() # исключаем строку "Итого"
104
+ df_percentage = df[['№ сметы', 'Наименование']].copy()
105
  df_percentage['Процент от общей суммы'] = ((df['ВСЕГО ПО СМЕТЕ'].iloc[:-1] / total_sum) * 100).round(2)
106
 
107
  # Создание круговой диаграммы
 
141
  detailed_report_path = os.path.join(temp_dir, "detailed_report.xlsx")
142
  percentage_report_path = os.path.join(temp_dir, "percentage_report.xlsx")
143
 
144
+ # Сохраняем DataFrame с настройками стиля
145
+ save_to_excel_with_styles(df, detailed_report_path)
146
  df_percentage.to_excel(percentage_report_path, index=False)
147
 
148
  # Возвращаем пути к файлам и диаграмму
149
  return df, df_percentage, pie_chart, detailed_report_path, percentage_report_path
150
 
151
+ # Функция для сохранения DataFrame в Excel с форматированием
152
+ def save_to_excel_with_styles(df, filepath):
153
+ writer = pd.ExcelWriter(filepath, engine='openpyxl')
154
+ df.to_excel(writer, index=False)
155
+ workbook = writer.book
156
+ worksheet = writer.sheets['Sheet1']
157
+
158
+ # Устанавливаем шрифт Intern размером 12 для всех ячеек
159
+ intern_font = Font(name='Intern', size=12)
160
+ for row in worksheet.iter_rows():
161
+ for cell in row:
162
+ cell.font = intern_font
163
+
164
+ # Устанавливаем ширину столбцов и цвет заливки
165
+ column_widths = {
166
+ 'A': 16, 'B': 50, 'C': 18, 'D': 18, 'E': 18, 'F': 18, 'G': 18, 'H': 18
167
+ }
168
+ fill_colors = {
169
+ 'C': 'DCEDFC', 'D': '94B4D4', 'E': '3866C9',
170
+ 'F': 'DCEDFC', 'G': '94B4D4', 'H': '3866C9'
171
+ }
172
+
173
+ for col, width in column_widths.items():
174
+ worksheet.column_dimensions[col].width = width
175
+
176
+ for col, color in fill_colors.items():
177
+ for cell in worksheet[col]:
178
+ cell.fill = PatternFill(start_color=color, end_color=color, fill_type="solid")
179
+
180
+ writer.save()
181
+
182
  # CSS для блокировки копирования текста
183
  custom_css = """
184
  * {
 
189
  }
190
  """
191
 
192
+ # Интерфейс Gradio
193
  with gr.Blocks(css=custom_css) as demo:
 
194
  with gr.Row():
195
+ gr.Markdown("### **AIGineer | ИИ УПРАВЛЕНИЕ СТРОИТЕЛЬСТВОМ**")
196
+ gr.Markdown("**На текущий момент система считает сметы в ценах от 2023**")
197
 
 
198
  with gr.Row():
199
+ upload_button = gr.File(label="ЗАГРУЗИТЕ СМЕТУ В PDF")
200
 
 
 
 
 
 
201
  with gr.Row():
202
+ gr.Markdown("<h3 style='text-align: center;'>ДЕТАЛИЗИРОВАННЫЙ БЮДЖЕТ</h3>")
203
  with gr.Row():
204
+ output_table_1 = gr.Dataframe(headers=["№ сметы", "Наименование", "Рабочие", "Техника", "Материалы", "Перевозки", "Оборудование", "ВСЕГО ПО СМЕТЕ"])
205
 
 
 
 
 
 
 
 
206
  with gr.Row():
207
+ gr.Markdown("<h3 style='text-align: center;'>ПРОЦЕНТНОЕ РАСПРЕДЕЛЕНИЕ ЛОКАЛЬНЫХ СМЕТ</h3>")
208
  with gr.Row():
209
+ output_table_2 = gr.Dataframe(headers=["№ сметы", "Наименование", "Процент от общей суммы"])
210
 
 
211
  with gr.Row():
212
+ gr.Markdown("<h3 style='text-align: center;'>СТРУКТУРА РАСХОДОВ ПО КАТЕГОРИЯМ</h3>")
213
  with gr.Row():
214
+ output_plot = gr.Image(type="pil")
215
 
 
216
  with gr.Row():
217
  download_excel_1 = gr.File(label="Скачать детализированный отчет")
218
  download_excel_2 = gr.File(label="Скачать процентное соотношение")