-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathextract_xlsm_data.py
More file actions
147 lines (123 loc) · 5.95 KB
/
extract_xlsm_data.py
File metadata and controls
147 lines (123 loc) · 5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import openpyxl
from openpyxl.styles import Font, PatternFill, Border, Alignment
from openpyxl.utils import get_column_letter
import os
def extract_xlsm_data(input_file, output_file):
"""
Extract all data from a VBA-locked .xlsm file to a new unlocked .xlsx file.
This bypasses VBA password protection by only reading data (not macros).
"""
try:
print(f"Opening file: {input_file}")
# Load the workbook (data_only=True reads values, not formulas)
# keep_vba=False removes all VBA macros and bypasses password
wb_input = openpyxl.load_workbook(input_file, data_only=True, keep_vba=False)
# Create a new workbook for output
wb_output = openpyxl.Workbook()
wb_output.remove(wb_output.active) # Remove default sheet
print(f"\nFound {len(wb_input.sheetnames)} sheets")
# Copy each sheet
for sheet_name in wb_input.sheetnames:
print(f"Processing sheet: {sheet_name}")
source_sheet = wb_input[sheet_name]
target_sheet = wb_output.create_sheet(title=sheet_name)
# Copy all cell values and basic formatting
for row in source_sheet.iter_rows():
for cell in row:
target_cell = target_sheet[cell.coordinate]
# Copy value
target_cell.value = cell.value
# Copy basic formatting if exists
try:
if cell.font:
target_cell.font = Font(
name=cell.font.name,
size=cell.font.size,
bold=cell.font.bold,
italic=cell.font.italic,
color=cell.font.color
)
if cell.fill:
target_cell.fill = PatternFill(
fill_type=cell.fill.fill_type,
fgColor=cell.fill.fgColor,
bgColor=cell.fill.bgColor
)
if cell.alignment:
target_cell.alignment = Alignment(
horizontal=cell.alignment.horizontal,
vertical=cell.alignment.vertical,
wrap_text=cell.alignment.wrap_text
)
if cell.number_format:
target_cell.number_format = cell.number_format
except:
pass # Skip if formatting fails
# Copy column widths
for col in source_sheet.column_dimensions:
try:
if source_sheet.column_dimensions[col].width:
target_sheet.column_dimensions[col].width = source_sheet.column_dimensions[col].width
except:
pass
# Copy row heights
for row in source_sheet.row_dimensions:
try:
if source_sheet.row_dimensions[row].height:
target_sheet.row_dimensions[row].height = source_sheet.row_dimensions[row].height
except:
pass
# Copy merged cells
try:
for merged_cell_range in source_sheet.merged_cells.ranges:
target_sheet.merge_cells(str(merged_cell_range))
except:
pass
# Save the new unlocked workbook as .xlsx
wb_output.save(output_file)
print(f"\n✓ Successfully created unlocked file: {output_file}")
print("All data has been extracted without VBA macros")
wb_input.close()
wb_output.close()
return True
except FileNotFoundError:
print(f"Error: File '{input_file}' not found")
return False
except PermissionError:
print(f"Error: Permission denied. Make sure the file is not open in Excel")
return False
except Exception as e:
print(f"Error: {str(e)}")
import traceback
traceback.print_exc()
return False
if __name__ == "__main__":
# Configuration
input_filename = "boq.xls" # Change this to your locked .xlsm file name
output_filename = "boq_file.xlsx" # Output file (will be .xlsx format)
print("=" * 60)
print("Excel VBA Password Bypass - .XLSM Data Extractor")
print("=" * 60)
print("\nThis tool extracts all data from VBA-locked .xlsm files")
print("Output will be saved as .xlsx format (without macros)\n")
# Check if input file exists
if not os.path.exists(input_filename):
print(f"Error: '{input_filename}' not found in current directory")
print(f"\nCurrent directory: {os.getcwd()}")
print("\nPlease either:")
print(f"1. Place your .xlsm file in the current directory")
print(f"2. Or update the 'input_filename' variable with the full path")
print("\nExample: input_filename = r'C:\\Users\\YourName\\Documents\\myfile.xlsm'")
else:
# Extract data
success = extract_xlsm_data(input_filename, output_filename)
if success:
print("\n" + "=" * 60)
print("IMPORTANT NOTES:")
print("=" * 60)
print("• VBA macros are NOT included (they were password-protected)")
print("• Formulas are converted to their calculated values")
print("• All visible data and formatting are preserved")
print("• Merged cells are preserved")
print("• The new file has no password protection")
print("• Output is in .xlsx format (macro-free)")