aakanksha77 commited on
Commit
0002c06
·
verified ·
1 Parent(s): b038164

Upload 5 files

Browse files
[00 12 10] 26251-100-3DR-S04-00001_002.docx.pdf ADDED
Binary file (362 kB). View file
 
app.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import streamlit as st
2
+ # import pandas as pd
3
+ # import tempfile
4
+ # import os
5
+ # from pdf_section_extractor import PDFSectionExtractor, convert_pdf_to_excel # Assuming your original code is in pdf_section_extractor.py
6
+
7
+ # def main():
8
+ # st.title("PDF to Excel Converter")
9
+ # st.write("Upload a PDF file to convert it to Excel format with sections and tables.")
10
+
11
+ # # File uploader
12
+ # uploaded_file = st.file_uploader("Choose a PDF file", type=['pdf'])
13
+
14
+ # if uploaded_file is not None:
15
+ # # Create a temporary file to store the uploaded PDF
16
+ # with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp_pdf:
17
+ # tmp_pdf.write(uploaded_file.getvalue())
18
+ # pdf_path = tmp_pdf.name
19
+
20
+ # # Create a temporary file for the Excel output
21
+ # with tempfile.NamedTemporaryFile(delete=False, suffix='.xlsx') as tmp_excel:
22
+ # excel_path = tmp_excel.name
23
+
24
+ # try:
25
+ # # Show progress bar
26
+ # with st.spinner('Converting PDF to Excel...'):
27
+ # success = convert_pdf_to_excel(pdf_path, excel_path)
28
+
29
+ # if success:
30
+ # st.success("Conversion completed successfully!")
31
+
32
+ # # Read the Excel file to create a download button
33
+ # with open(excel_path, 'rb') as file:
34
+ # excel_data = file.read()
35
+
36
+ # # Create download button
37
+ # st.download_button(
38
+ # label="Download Excel file",
39
+ # data=excel_data,
40
+ # file_name=f"{uploaded_file.name.rsplit('.', 1)[0]}.xlsx",
41
+ # mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
42
+ # )
43
+
44
+ # # Preview the sections
45
+ # st.subheader("Preview of Extracted Sections")
46
+ # try:
47
+ # df_sections = pd.read_excel(excel_path, sheet_name='Sections')
48
+ # st.dataframe(df_sections)
49
+ # except Exception as e:
50
+ # st.error(f"Error displaying preview: {str(e)}")
51
+
52
+ # else:
53
+ # st.error("Failed to convert PDF to Excel. Please try again.")
54
+
55
+ # except Exception as e:
56
+ # st.error(f"An error occurred: {str(e)}")
57
+
58
+ # finally:
59
+ # # Clean up temporary files
60
+ # try:
61
+ # os.unlink(pdf_path)
62
+ # os.unlink(excel_path)
63
+ # except Exception as e:
64
+ # st.warning(f"Error cleaning up temporary files: {str(e)}")
65
+
66
+ # if __name__ == "__main__":
67
+ # main()
68
+
69
+
70
+ import streamlit as st
71
+ import tempfile
72
+ import os
73
+ from pdf_section_extractor import PDFSectionExtractor, convert_pdf_to_excel
74
+
75
+ def main():
76
+ st.title("PDF to Excel Converter")
77
+ st.write("Upload a PDF file to convert it to Excel format with sections and tables.")
78
+
79
+ # File uploader
80
+ uploaded_file = st.file_uploader("Choose a PDF file", type=['pdf'])
81
+
82
+ if uploaded_file is not None:
83
+ # Create a temporary file to store the uploaded PDF
84
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp_pdf:
85
+ tmp_pdf.write(uploaded_file.getvalue())
86
+ pdf_path = tmp_pdf.name
87
+
88
+ # Create a temporary file for the Excel output
89
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.xlsx') as tmp_excel:
90
+ excel_path = tmp_excel.name
91
+
92
+ try:
93
+ # Show progress bar
94
+ with st.spinner('Converting PDF to Excel...'):
95
+ # Use your existing convert_pdf_to_excel function
96
+ success = convert_pdf_to_excel(pdf_path, excel_path)
97
+
98
+ if success:
99
+ st.success("Conversion completed successfully!")
100
+
101
+ # Read the Excel file to create a download button
102
+ with open(excel_path, 'rb') as file:
103
+ excel_data = file.read()
104
+
105
+ # Create download button
106
+ st.download_button(
107
+ label="Download Excel file",
108
+ data=excel_data,
109
+ file_name=f"{uploaded_file.name.rsplit('.', 1)[0]}.xlsx",
110
+ mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
111
+ )
112
+
113
+ else:
114
+ st.error("Failed to convert PDF to Excel. Please try again.")
115
+
116
+ except Exception as e:
117
+ st.error(f"An error occurred: {str(e)}")
118
+
119
+ finally:
120
+ # Clean up temporary files
121
+ try:
122
+ os.unlink(pdf_path)
123
+ os.unlink(excel_path)
124
+ except Exception as e:
125
+ st.warning(f"Error cleaning up temporary files: {str(e)}")
126
+
127
+ if __name__ == "__main__":
128
+ main()
code4.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pdfplumber
2
+ import pandas as pd
3
+ import re
4
+ from typing import List, Dict, Tuple, Any
5
+
6
+ class PDFSectionExtractor:
7
+ def __init__(self, pdf_path: str):
8
+ """Initialize with path to PDF file."""
9
+ self.pdf_path = pdf_path
10
+ self.tables = []
11
+ self.table_names = {} # Store table names and their content
12
+
13
+ def is_level_three_section(self, section_number: str) -> bool:
14
+ """Check if the section number is a level three section (e.g., 2.1.1)."""
15
+ return len(section_number.split('.')) == 3
16
+
17
+ def find_table_names(self, text: str) -> List[Dict[str, str]]:
18
+ """Extract table names from text."""
19
+ table_pattern = r'\*\*Table\s+(\d+):\s+([^*]+)\*\*'
20
+ return [(match.group(1), match.group(2).strip())
21
+ for match in re.finditer(table_pattern, text)]
22
+
23
+ def clean_content(self, content: str) -> str:
24
+ """Remove table references and names from content."""
25
+ # Remove table references
26
+ content = re.sub(r'\*\*Table\s+\d+:\s+[^*]+\*\*', '', content)
27
+ # Remove any empty lines created
28
+ content = '\n'.join(line for line in content.split('\n') if line.strip())
29
+ return content
30
+
31
+ def merge_split_tables(self, tables: List[List]) -> List[List]:
32
+ """Merge tables that are split across pages."""
33
+ merged_tables = []
34
+ current_table = None
35
+
36
+ for table in tables:
37
+ if not table:
38
+ continue
39
+
40
+ if current_table is None:
41
+ current_table = table
42
+ else:
43
+ # Check if this table is a continuation
44
+ # Compare the number of columns
45
+ if len(table[0]) == len(current_table[0]):
46
+ current_table.extend(table)
47
+ else:
48
+ merged_tables.append(current_table)
49
+ current_table = table
50
+
51
+ if current_table:
52
+ merged_tables.append(current_table)
53
+
54
+ return merged_tables
55
+
56
+ def extract_tables(self) -> List[Dict[str, Any]]:
57
+ """Extract tables with their names and merge split tables."""
58
+ tables_data = []
59
+ current_section = None
60
+ current_table_data = None
61
+ current_table_name = None
62
+
63
+ with pdfplumber.open(self.pdf_path) as pdf:
64
+ for page in pdf.pages:
65
+ text = page.extract_text(x_tolerance=1,y_tolerance=0) or ''
66
+
67
+ # Find table names in the text
68
+ table_names = self.find_table_names(text)
69
+ tables = page.extract_tables()
70
+
71
+ # Process each table found
72
+ if tables:
73
+ tables = self.merge_split_tables(tables)
74
+
75
+ for i, table in enumerate(tables):
76
+ table_name = None
77
+ if i < len(table_names):
78
+ table_num, name = table_names[i]
79
+ table_name = f"Table {table_num}: {name}"
80
+
81
+ if table: # Check if table has content
82
+ df = pd.DataFrame(table)
83
+ # Clean the DataFrame
84
+ df = df.dropna(how='all').dropna(axis=1, how='all')
85
+ # Replace None with empty string
86
+ df = df.fillna('')
87
+
88
+ tables_data.append({
89
+ 'name': table_name,
90
+ 'data': df
91
+ })
92
+
93
+ return tables_data
94
+
95
+ def extract_sections(self) -> List[Dict[str, str]]:
96
+ """Extract sections from PDF with content, excluding tables."""
97
+ sections = []
98
+ current_section = None
99
+ current_content = []
100
+ section_pattern = r'^(\d+\.(?:\d+)?(?:\.\d+)?)\s+(.+)$'
101
+
102
+ with pdfplumber.open(self.pdf_path) as pdf:
103
+ for page in pdf.pages:
104
+ text = page.extract_text(x_tolerance=1)
105
+ if not text:
106
+ continue
107
+
108
+ lines = text.split('\n')
109
+
110
+ for line in lines:
111
+ match = re.match(section_pattern, line.strip())
112
+
113
+ if match:
114
+ if current_section:
115
+ content_text = '\n'.join(current_content)
116
+ content_text = self.clean_content(content_text)
117
+
118
+ if self.is_level_three_section(current_section[0]):
119
+ full_content = current_section[1] + '\n' + content_text
120
+ sections.append({
121
+ 'section_number': current_section[0],
122
+ 'section_name': '',
123
+ 'content': full_content
124
+ })
125
+ else:
126
+ sections.append({
127
+ 'section_number': current_section[0],
128
+ 'section_name': current_section[1],
129
+ 'content': content_text
130
+ })
131
+
132
+ current_section = (match.group(1), match.group(2))
133
+ current_content = []
134
+ elif current_section:
135
+ current_content.append(line.strip())
136
+
137
+ # Handle the last section
138
+ if current_section:
139
+ content_text = '\n'.join(current_content)
140
+ content_text = self.clean_content(content_text)
141
+
142
+ if self.is_level_three_section(current_section[0]):
143
+ full_content = current_section[1] + '\n' + content_text
144
+ sections.append({
145
+ 'section_number': current_section[0],
146
+ 'section_name': '',
147
+ 'content': full_content
148
+ })
149
+ else:
150
+ sections.append({
151
+ 'section_number': current_section[0],
152
+ 'section_name': current_section[1],
153
+ 'content': content_text
154
+ })
155
+
156
+ return sections
157
+
158
+ def convert_pdf_to_excel(pdf_path: str, excel_path: str):
159
+ """Convert PDF with sections and tables to Excel file."""
160
+ try:
161
+ extractor = PDFSectionExtractor(pdf_path)
162
+ sections = extractor.extract_sections()
163
+ tables = extractor.extract_tables()
164
+
165
+ with pd.ExcelWriter(excel_path, engine='openpyxl') as writer:
166
+ # Write sections to main sheet
167
+ df_sections = pd.DataFrame(sections)
168
+ df_sections.to_excel(writer, index=False, sheet_name='Sections')
169
+
170
+ # Auto-adjust sections sheet
171
+ worksheet = writer.sheets['Sections']
172
+ for idx, col in enumerate(['A', 'B', 'C']):
173
+ worksheet.column_dimensions[col].width = 15 if idx < 2 else 50
174
+
175
+ # Write tables to separate sheets
176
+ for i, table_info in enumerate(tables, 1):
177
+ if table_info['name']:
178
+ sheet_name = table_info['name'][:31] # Excel sheet name length limit
179
+ else:
180
+ sheet_name = f'Table_{i}'
181
+
182
+ # Write table data
183
+ table_info['data'].to_excel(writer, sheet_name=sheet_name, index=False)
184
+
185
+ # Auto-adjust table sheet
186
+ worksheet = writer.sheets[sheet_name]
187
+ for column in worksheet.columns:
188
+ max_length = 0
189
+ column = [cell for cell in column]
190
+ for cell in column:
191
+ try:
192
+ if len(str(cell.value)) > max_length:
193
+ max_length = len(cell.value)
194
+ except:
195
+ pass
196
+ adjusted_width = (max_length + 2)
197
+ worksheet.column_dimensions[column[0].column_letter].width = adjusted_width
198
+
199
+ return True
200
+
201
+ except Exception as e:
202
+ print(f"Error converting PDF to Excel: {str(e)}")
203
+ return False
204
+
205
+ if __name__ == "__main__":
206
+ pdf_path = "/Users/aakanksha.n/Desktop/pdf_to_excel/[00 12 10] 26251-100-3DR-S04-00001_002.docx.pdf"
207
+ excel_path = "/Users/aakanksha.n/Desktop/pdf_to_excel/format4.xlsx"
208
+
209
+ success = convert_pdf_to_excel(pdf_path, excel_path)
210
+ if success:
211
+ print("Successfully converted PDF to Excel!")
212
+ else:
213
+ print("Failed to convert PDF to Excel.")
format.xlsx ADDED
Binary file (46 kB). View file
 
pdf_section_extractor.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pdfplumber
2
+ import pandas as pd
3
+ import re
4
+ from typing import List, Dict, Tuple, Any
5
+
6
+ class PDFSectionExtractor:
7
+ def __init__(self, pdf_path: str):
8
+ """Initialize with path to PDF file."""
9
+ self.pdf_path = pdf_path
10
+ self.tables = []
11
+ self.table_names = {} # Store table names and their content
12
+
13
+ def is_level_three_section(self, section_number: str) -> bool:
14
+ """Check if the section number is a level three section (e.g., 2.1.1)."""
15
+ return len(section_number.split('.')) == 3
16
+
17
+ def find_table_names(self, text: str) -> List[Dict[str, str]]:
18
+ """Extract table names from text."""
19
+ table_pattern = r'\*\*Table\s+(\d+):\s+([^*]+)\*\*'
20
+ return [(match.group(1), match.group(2).strip())
21
+ for match in re.finditer(table_pattern, text)]
22
+
23
+ def clean_content(self, content: str) -> str:
24
+ """Remove table references and names from content."""
25
+ # Remove table references
26
+ content = re.sub(r'\*\*Table\s+\d+:\s+[^*]+\*\*', '', content)
27
+ # Remove any empty lines created
28
+ content = '\n'.join(line for line in content.split('\n') if line.strip())
29
+ return content
30
+
31
+ def merge_split_tables(self, tables: List[List]) -> List[List]:
32
+ """Merge tables that are split across pages."""
33
+ merged_tables = []
34
+ current_table = None
35
+
36
+ for table in tables:
37
+ if not table:
38
+ continue
39
+
40
+ if current_table is None:
41
+ current_table = table
42
+ else:
43
+ # Check if this table is a continuation
44
+ # Compare the number of columns
45
+ if len(table[0]) == len(current_table[0]):
46
+ current_table.extend(table)
47
+ else:
48
+ merged_tables.append(current_table)
49
+ current_table = table
50
+
51
+ if current_table:
52
+ merged_tables.append(current_table)
53
+
54
+ return merged_tables
55
+
56
+ def extract_tables(self) -> List[Dict[str, Any]]:
57
+ """Extract tables with their names and merge split tables."""
58
+ tables_data = []
59
+ current_section = None
60
+ current_table_data = None
61
+ current_table_name = None
62
+
63
+ with pdfplumber.open(self.pdf_path) as pdf:
64
+ for page in pdf.pages:
65
+ text = page.extract_text(x_tolerance=1,y_tolerance=0) or ''
66
+
67
+ # Find table names in the text
68
+ table_names = self.find_table_names(text)
69
+ tables = page.extract_tables()
70
+
71
+ # Process each table found
72
+ if tables:
73
+ tables = self.merge_split_tables(tables)
74
+
75
+ for i, table in enumerate(tables):
76
+ table_name = None
77
+ if i < len(table_names):
78
+ table_num, name = table_names[i]
79
+ table_name = f"Table {table_num}: {name}"
80
+
81
+ if table: # Check if table has content
82
+ df = pd.DataFrame(table)
83
+ # Clean the DataFrame
84
+ df = df.dropna(how='all').dropna(axis=1, how='all')
85
+ # Replace None with empty string
86
+ df = df.fillna('')
87
+
88
+ tables_data.append({
89
+ 'name': table_name,
90
+ 'data': df
91
+ })
92
+
93
+ return tables_data
94
+
95
+ def extract_sections(self) -> List[Dict[str, str]]:
96
+ """Extract sections from PDF with content, excluding tables."""
97
+ sections = []
98
+ current_section = None
99
+ current_content = []
100
+ section_pattern = r'^(\d+\.(?:\d+)?(?:\.\d+)?)\s+(.+)$'
101
+
102
+ with pdfplumber.open(self.pdf_path) as pdf:
103
+ for page in pdf.pages:
104
+ text = page.extract_text(x_tolerance=1)
105
+ if not text:
106
+ continue
107
+
108
+ lines = text.split('\n')
109
+
110
+ for line in lines:
111
+ match = re.match(section_pattern, line.strip())
112
+
113
+ if match:
114
+ if current_section:
115
+ content_text = '\n'.join(current_content)
116
+ content_text = self.clean_content(content_text)
117
+
118
+ if self.is_level_three_section(current_section[0]):
119
+ full_content = current_section[1] + '\n' + content_text
120
+ sections.append({
121
+ 'section_number': current_section[0],
122
+ 'section_name': '',
123
+ 'content': full_content
124
+ })
125
+ else:
126
+ sections.append({
127
+ 'section_number': current_section[0],
128
+ 'section_name': current_section[1],
129
+ 'content': content_text
130
+ })
131
+
132
+ current_section = (match.group(1), match.group(2))
133
+ current_content = []
134
+ elif current_section:
135
+ current_content.append(line.strip())
136
+
137
+ # Handle the last section
138
+ if current_section:
139
+ content_text = '\n'.join(current_content)
140
+ content_text = self.clean_content(content_text)
141
+
142
+ if self.is_level_three_section(current_section[0]):
143
+ full_content = current_section[1] + '\n' + content_text
144
+ sections.append({
145
+ 'section_number': current_section[0],
146
+ 'section_name': '',
147
+ 'content': full_content
148
+ })
149
+ else:
150
+ sections.append({
151
+ 'section_number': current_section[0],
152
+ 'section_name': current_section[1],
153
+ 'content': content_text
154
+ })
155
+
156
+ return sections
157
+
158
+ def convert_pdf_to_excel(pdf_path: str, excel_path: str):
159
+ """Convert PDF with sections and tables to Excel file."""
160
+ try:
161
+ extractor = PDFSectionExtractor(pdf_path)
162
+ sections = extractor.extract_sections()
163
+ tables = extractor.extract_tables()
164
+
165
+ with pd.ExcelWriter(excel_path, engine='openpyxl') as writer:
166
+ # Write sections to main sheet
167
+ df_sections = pd.DataFrame(sections)
168
+ df_sections.to_excel(writer, index=False, sheet_name='Sections')
169
+
170
+ # Auto-adjust sections sheet
171
+ worksheet = writer.sheets['Sections']
172
+ for idx, col in enumerate(['A', 'B', 'C']):
173
+ worksheet.column_dimensions[col].width = 15 if idx < 2 else 50
174
+
175
+ # Write tables to separate sheets
176
+ for i, table_info in enumerate(tables, 1):
177
+ if table_info['name']:
178
+ sheet_name = table_info['name'][:31] # Excel sheet name length limit
179
+ else:
180
+ sheet_name = f'Table_{i}'
181
+
182
+ # Write table data
183
+ table_info['data'].to_excel(writer, sheet_name=sheet_name, index=False)
184
+
185
+ # Auto-adjust table sheet
186
+ worksheet = writer.sheets[sheet_name]
187
+ for column in worksheet.columns:
188
+ max_length = 0
189
+ column = [cell for cell in column]
190
+ for cell in column:
191
+ try:
192
+ if len(str(cell.value)) > max_length:
193
+ max_length = len(cell.value)
194
+ except:
195
+ pass
196
+ adjusted_width = (max_length + 2)
197
+ worksheet.column_dimensions[column[0].column_letter].width = adjusted_width
198
+
199
+ return True
200
+
201
+ except Exception as e:
202
+ print(f"Error converting PDF to Excel: {str(e)}")
203
+ return False
204
+
205
+ if __name__ == "__main__":
206
+ pdf_path = "/Users/aakanksha.n/Desktop/pdf_to_excel/[00 12 10] 26251-100-3DR-S04-00001_002.docx.pdf"
207
+ excel_path = "/Users/aakanksha.n/Desktop/pdf_to_excel/format4.xlsx"
208
+
209
+ success = convert_pdf_to_excel(pdf_path, excel_path)
210
+ if success:
211
+ print("Successfully converted PDF to Excel!")
212
+ else:
213
+ print("Failed to convert PDF to Excel.")