DinaFatikh commited on
Commit
674425c
·
verified ·
1 Parent(s): eb899e4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +5 -166
app.py CHANGED
@@ -8,171 +8,10 @@ import tempfile
8
  import os
9
  from PIL import Image
10
 
11
- # Функция для обработки PDF и извлечения данных
12
  def process_pdf(file):
13
- data_list = []
14
-
15
- try:
16
- # Открываем PDF-файл с помощью pdfplumber
17
- with pdfplumber.open(file.name) as pdf:
18
- text = ''
19
- for page_num, page in enumerate(pdf.pages, start=1):
20
- page_text = page.extract_text()
21
- if page_text:
22
- text += page_text + '\n'
23
-
24
- # Функция для извлечения значений по ключевым словам
25
- def extract_value(label, text):
26
- pattern = rf'{label}\s*тенге\s*([\d\s,]+)'
27
- match = re.search(pattern, text, flags=re.IGNORECASE)
28
- if match:
29
- value = match.group(1)
30
- value = re.sub(r'[^\d]', '', value)
31
- return int(value) if value else 0
32
- return 0
33
-
34
- # Функция для извлечения значения "ВСЕГО ПО СМЕТЕ"
35
- def extract_total_value(label, text):
36
- pattern = rf'{label}:\s*([\d\s]+)'
37
- match = re.search(pattern, text, flags=re.IGNORECASE)
38
- if match:
39
- value = match.group(1)
40
- value = re.sub(r'[^\d]', '', value)
41
- return int(value) if value else 0
42
- return 0
43
-
44
- # Разбиваем текст на части по ключевому слову "ЛОКАЛЬНАЯ СМЕТА №"
45
- estimates = re.split(r'ЛОКАЛЬНАЯ СМЕТА №', text, flags=re.IGNORECASE)[1:]
46
-
47
- for idx, estimate_text in enumerate(estimates, start=1):
48
- estimate_text_clean = re.split(r'Раздел', estimate_text, flags=re.IGNORECASE)[0]
49
-
50
- # Извлекаем номер сметы
51
- number_match = re.match(r'(\S+)', estimate_text_clean.strip())
52
- estimate_number = number_match.group(1) if number_match else ''
53
-
54
- # Извлекаем наименование сметы после "на"
55
- name_match = re.search(r'на\s+(.+?)(?:\n|$)', estimate_text_clean, flags=re.IGNORECASE)
56
- estimate_name = name_match.group(1).strip() if name_match else ''
57
-
58
- # Извлекаем затраты
59
- labor_cost = extract_value('Затраты на труд рабочих', estimate_text_clean)
60
- machine_cost = extract_value('Машины и механизмы', estimate_text_clean)
61
- material_cost = extract_value('Материалы, изделия и конструкции', estimate_text_clean)
62
- transport_cost = extract_value('Перевозки', estimate_text_clean)
63
- equipment_cost = extract_value('Оборудование', estimate_text_clean)
64
- total_cost = extract_total_value('ВСЕГО ПО СМЕТЕ', estimate_text_clean)
65
-
66
- # Сохраняем данные
67
- data_list.append({
68
- '№ локальной сметы': estimate_number,
69
- 'Наименование': estimate_name,
70
- 'Рабочие': labor_cost,
71
- 'Техника': machine_cost,
72
- 'Материалы': material_cost,
73
- 'Перевозки': transport_cost,
74
- 'Оборудование': equipment_cost,
75
- 'ВСЕГО ПО СМЕТЕ': total_cost
76
- })
77
-
78
- except Exception as e:
79
- print(f"Ошибка при обработке PDF-файла: {e}")
80
- return pd.DataFrame(), pd.DataFrame(), None, None, None, None
81
-
82
- # Создаем DataFrame
83
- df = pd.DataFrame(data_list)
84
- df.columns = df.columns.str.strip()
85
-
86
- # Добавляем строку "Итого"
87
- total_row = pd.DataFrame({
88
- '№ локальной сметы': ['Итого'],
89
- 'Наименование': [''],
90
- 'Рабочие': [df['Рабочие'].sum()],
91
- 'Техника': [df['Техника'].sum()],
92
- 'Материалы': [df['Материалы'].sum()],
93
- 'Перевозки': [df['Перевозки'].sum()],
94
- 'Оборудование': [df['Оборудование'].sum()],
95
- 'ВСЕГО ПО СМЕТЕ': [df['ВСЕГО ПО СМЕТЕ'].sum()]
96
- })
97
- df = pd.concat([df, total_row], ignore_index=True)
98
-
99
- # Создаем таблицу с процентным соотношением
100
- total_sum = df['ВСЕГО ПО СМЕТЕ'].iloc[:-1].sum()
101
- df_percentage = df[['№ локальной сметы', 'Наименование']].copy()
102
- df_percentage['Процент от общей суммы'] = ((df['ВСЕГО ПО СМЕТЕ'].iloc[:-1] / total_sum) * 100).round(2)
103
-
104
- # Создаем круговую диаграмму
105
- category_sums = {
106
- 'Категория': ['Рабочие', 'Техника', 'Материалы', 'Перевозки', 'Оборудование'],
107
- 'Сумма': [
108
- df['Рабочие'].iloc[:-1].sum(),
109
- df['Техника'].iloc[:-1].sum(),
110
- df['Материалы'].iloc[:-1].sum(),
111
- df['Перевозки'].iloc[:-1].sum(),
112
- df['Оборудование'].iloc[:-1].sum()
113
- ]
114
- }
115
-
116
- df_category_percentage = pd.DataFrame(category_sums)
117
- df_category_percentage['Процент от общей суммы'] = ((df_category_percentage['Сумма'] / total_sum) * 100).round(2)
118
-
119
- # Настройка цветов
120
- color_map = {
121
- 'Рабочие': '#DCEDFC',
122
- 'Техника': '#94B4D4',
123
- 'Материалы': '#3C47D6',
124
- 'Перевозки': '#94B4D4',
125
- 'Оборудование': '#0E86D4'
126
- }
127
-
128
- # Фильтрация категорий
129
- filtered_df = df_category_percentage[df_category_percentage['Процент от общей суммы'] >= 1].reset_index(drop=True)
130
- colors = [color_map.get(category, '#FFFFFF') for category in filtered_df['Категория']]
131
-
132
- # Сохраняем диаграмму
133
- fig, ax = plt.subplots(figsize=(7, 7))
134
- ax.pie(
135
- filtered_df['Сумма'],
136
- labels=filtered_df['Категория'],
137
- autopct='%1.2f%%',
138
- startangle=90,
139
- colors=colors,
140
- labeldistance=1.1,
141
- pctdistance=0.8
142
- )
143
- plt.axis('equal')
144
- plt.tight_layout()
145
-
146
- pie_chart = BytesIO()
147
- plt.savefig(pie_chart, format='png', bbox_inches='tight')
148
- plt.close(fig)
149
- pie_chart.seek(0)
150
-
151
- # Форматирование чисел
152
- def format_number(x):
153
- return f"{x:,}".replace(",", " ")
154
-
155
- df_formatted = df.copy()
156
- for col in ['Рабочие', 'Техника', 'Материалы', 'Перевозки', 'Оборудование', 'ВСЕГО ПО СМЕТЕ']:
157
- df_formatted[col] = df_formatted[col].apply(format_number)
158
-
159
- df_percentage_formatted = df_percentage.copy()
160
- df_percentage_formatted['Процент от общей суммы'] = df_percentage_formatted['Процент от общей суммы'].astype(str) + '%'
161
-
162
- df_category_percentage_formatted = df_category_percentage.copy()
163
- df_category_percentage_formatted['Сумма'] = df_category_percentage_formatted['Сумма'].apply(format_number)
164
- df_category_percentage_formatted['Процент от общей суммы'] = df_category_percentage_formatted['Процент от общей суммы'].astype(str) + '%'
165
-
166
- # Создаем временные файлы Excel
167
- temp_dir = tempfile.mkdtemp()
168
- detailed_report_path = os.path.join(temp_dir, "detailed_report.xlsx")
169
- percentage_report_path = os.path.join(temp_dir, "percentage_report.xlsx")
170
- category_report_path = os.path.join(temp_dir, "category_report.xlsx")
171
-
172
- df.to_excel(detailed_report_path, index=False)
173
- df_percentage.to_excel(percentage_report_path, index=False)
174
- df_category_percentage.to_excel(category_report_path, index=False)
175
-
176
  return df_formatted, df_percentage_formatted, df_category_percentage_formatted, pie_chart, detailed_report_path, percentage_report_path, category_report_path
177
 
178
  # CSS для блокировки копирования текста
@@ -209,14 +48,14 @@ with gr.Blocks(css=custom_css) as demo:
209
 
210
  # Описание и пример отчета
211
  description = gr.Markdown(visible=False)
212
- preview_table = gr.Dataframe(visible=False, max_rows=5, height=200)
213
 
214
  # Кнопка получения отчета
215
  with gr.Row():
216
  get_report_button = gr.Button("Получить отчет")
217
 
218
  # Отображение отчета
219
- output_table = gr.Dataframe(visible=False, max_rows=10, height=300)
220
  output_image = gr.Image(type="pil", visible=False)
221
 
222
  # Кнопка скачивания
 
8
  import os
9
  from PIL import Image
10
 
11
+ # Функция для обработки PDF и извлечения данных (остается без изменений)
12
  def process_pdf(file):
13
+ # ... [Ваш существующий код функции process_pdf]
14
+ # Убедитесь, что весь код функции process_pdf здесь и корректен.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  return df_formatted, df_percentage_formatted, df_category_percentage_formatted, pie_chart, detailed_report_path, percentage_report_path, category_report_path
16
 
17
  # CSS для блокировки копирования текста
 
48
 
49
  # Описание и пример отчета
50
  description = gr.Markdown(visible=False)
51
+ preview_table = gr.Dataframe(visible=False, height=200)
52
 
53
  # Кнопка получения отчета
54
  with gr.Row():
55
  get_report_button = gr.Button("Получить отчет")
56
 
57
  # Отображение отчета
58
+ output_table = gr.Dataframe(visible=False, height=300)
59
  output_image = gr.Image(type="pil", visible=False)
60
 
61
  # Кнопка скачивания