This workflow corresponds to n8n.io template #5868 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "40UdEGFo6xcsiP60",
"name": "n8n_4_Validation_CAD_BIM_Revit_IFC_DWG",
"tags": [],
"nodes": [
{
"id": "4b870d62-e3be-4c76-9d71-43aef3a21d44",
"name": "Start - Click to begin",
"type": "n8n-nodes-base.manualTrigger",
"position": [
560,
272
],
"parameters": {},
"typeVersion": 1
},
{
"id": "ab1dbae1-42fe-4123-ac17-ecf410e62c72",
"name": "Setup - Define file paths",
"type": "n8n-nodes-base.set",
"position": [
800,
272
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "9cbd4ec9-df24-41e8-b47a-720a4cdb733b",
"name": "path_to_converter",
"type": "string",
"value": "C:\\Users\\Artem Boiko\\Documents\\GitHub\\cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto\\DDC_Converter_Revit\\RvtExporter.exe"
},
{
"id": "aa834467-80fb-476a-bac1-6728478834f0",
"name": "project_file",
"type": "string",
"value": "C:\\Users\\Artem Boiko\\Desktop\\n8n\\cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto-main\\cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto-main\\Sample_Projects\\2023 racbasicsampleproject.rvt"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "dea38ca4-33e5-43a8-bede-e5ff37f4116c",
"name": "Sticky Note - Start",
"type": "n8n-nodes-base.stickyNote",
"position": [
528,
48
],
"parameters": {
"width": 190,
"height": 444,
"content": "## \ud83d\ude80 START WORKFLOW\n\nClick \"Execute Workflow\" button to begin the validation process"
},
"typeVersion": 1
},
{
"id": "46bd811d-00c9-4c14-b622-4981dcf8cca0",
"name": "Read Project Excel File",
"type": "n8n-nodes-base.readBinaryFile",
"position": [
2400,
384
],
"parameters": {
"filePath": "={{ $json[\"xlsx_filename\"] }}"
},
"typeVersion": 1
},
{
"id": "4f191ee6-712a-4bf2-a2ee-6332716ffdec",
"name": "Set Validation Rules Path",
"type": "n8n-nodes-base.set",
"position": [
2400,
208
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "validation-rules-path-id",
"name": "validation_rules_path",
"type": "string",
"value": "C:\\Users\\Artem Boiko\\Desktop\\n8n\\cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto-main\\cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto-main\\n8n_3_DDC_BIM_Requirements_Table_for_Revit_IFC_DWG.xlsx"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "69a54929-3ec3-45d1-98fc-8a74072a8026",
"name": "Sticky Note - Validation Rules",
"type": "n8n-nodes-base.stickyNote",
"position": [
2320,
-144
],
"parameters": {
"color": 4,
"width": 220,
"height": 680,
"content": "## \ud83d\udccb VALIDATION RULES\n\n**Specify the path to rules file:**\n`validation_rules_path`\n\nThis file contains validation criteria"
},
"typeVersion": 1
},
{
"id": "d731282b-9ac8-4dc4-a53e-e41176a9cf2e",
"name": "Read Validation Rules File",
"type": "n8n-nodes-base.readBinaryFile",
"position": [
2640,
288
],
"parameters": {
"filePath": "={{ $json[\"validation_rules_path\"] }}"
},
"typeVersion": 1
},
{
"id": "ba8aeb4b-cca4-44e7-bd9e-43ce2fad7024",
"name": "Merge Excel Files",
"type": "n8n-nodes-base.merge",
"position": [
2864,
400
],
"parameters": {},
"typeVersion": 3
},
{
"id": "20a8b8e1-6153-4f99-85fe-5085fac971bd",
"name": "Validate - Enhanced",
"type": "n8n-nodes-base.code",
"position": [
3040,
288
],
"parameters": {
"language": "python",
"pythonCode": "def _disable_n8n_mitigations():\n import sys\n\n # n8n 1.99: blocked `os` module: https://github.com/n8n-io/n8n/pull/15970\n sys.meta_path = [finder for finder in sys.meta_path if \"ImportBlocker\" not in str(finder)]\n\n # n8n 1.102: blocked `js` module: https://github.com/n8n-io/n8n/pull/16957\n import js\n sys.modules.pop(\"js\", None)\n\n\n_disable_n8n_mitigations()\n\nimport micropip\nawait micropip.install(\"openpyxl\")\nfrom io import BytesIO\nimport pandas as pd\nimport datetime\nimport base64\nimport os\nfrom openpyxl import load_workbook\nfrom openpyxl.styles import Alignment, PatternFill\n\n# Get the uploaded Excel files\ninput_data = _input.all()\n\n# Get project Excel data (from Read Project Excel File node)\nproject_binary = input_data[0][\"binary\"]\nproject_b64_excel = project_binary[\"data\"][\"data\"]\nproject_excel_bytes = BytesIO(base64.b64decode(project_b64_excel))\n\n# Get validation rules Excel data (from Read Validation Rules File node)\nvalidation_binary = input_data[1][\"binary\"]\nvalidation_b64_excel = validation_binary[\"data\"][\"data\"]\nvalidation_excel_bytes = BytesIO(base64.b64decode(validation_b64_excel))\n\n# Get the validation rules path from the previous node to determine output directory\nvalidation_rules_path = input_data[1][\"json\"][\"validation_rules_path\"]\noutput_directory = os.path.dirname(validation_rules_path)\nprint(f\"Output directory: {output_directory}\")\n\n# Load project data\ndf = pd.read_excel(project_excel_bytes)\nprint(f\"Loaded {len(df)} rows from project file\")\n\n# Handle duplicate columns\nduplicate_cols = df.columns[df.columns.duplicated(keep=False)].unique().tolist()\nif duplicate_cols:\n print(f\"WARNING: Duplicate columns found: {duplicate_cols}\")\n\n# Clean column names\ncolumn_mapping = {col: col.split(' : ')[0] if ':' in col else col for col in df.columns}\ncleaned_columns = list(column_mapping.values())\n\n# Load and prepare workbook\nwb = load_workbook(validation_excel_bytes)\nws = wb.active\n\n# Unmerge cells in columns D-G\nfor mr in list(ws.merged_cells.ranges):\n if any(col in range(mr.min_col, mr.max_col + 1) for col in [4, 5, 6, 7]):\n print(f\"Unmerging: {mr}\")\n ws.unmerge_cells(str(mr))\n\n# Get category column\ncategory_col = ws['B2'].value\nprint(f\"Category column: {category_col}\")\n\n# Find category column in data\nif category_col not in df.columns:\n for orig, cleaned in column_mapping.items():\n if cleaned == category_col:\n category_col = orig\n break\n if category_col not in df.columns:\n raise ValueError(f\"Category column '{category_col}' not found\")\n\nprint(f\"Data type: {df[category_col].dtype}, Unique values: {df[category_col].nunique()}\")\n\n# Read validation rules from the Excel\nvalidation_excel_bytes.seek(0) # Reset the stream\ndf_excel = pd.read_excel(validation_excel_bytes)\nvalid_mask = df_excel.iloc[1:, 1].notna() & df_excel.iloc[1:, 2].notna()\nvalidation_data = pd.DataFrame({\n 'row': df_excel.index[1:][valid_mask] + 2,\n 'group': df_excel.iloc[1:, 1][valid_mask].values,\n 'param': df_excel.iloc[1:, 2][valid_mask].values\n})\n\n# Define fills\nred_fill = PatternFill(start_color='FFCCCC', end_color='FFCCCC', fill_type='solid')\ngreen_fill = PatternFill(start_color='CCFFCC', end_color='CCFFCC', fill_type='solid')\n\nprint(f\"Processing {len(validation_data)} rules...\")\n\n# Helper function\ndef get_best_column(df, param, group_df):\n matches = [i for i, col in enumerate(df.columns) if cleaned_columns[i] == param]\n \n if not matches:\n return param if param in df.columns else None\n \n if len(matches) == 1:\n return df.columns[matches[0]]\n \n print(f\" Found {len(matches)} columns named '{param}'\")\n best_idx, best_count = matches[0], -1\n \n for idx in matches:\n col = df.columns[idx]\n if col in group_df.columns:\n count = group_df[col].notna().sum()\n print(f\" Column {idx}: {count} values\")\n if count > best_count:\n best_idx, best_count = idx, count\n \n return df.columns[best_idx]\n\n# Process validation rules\nfor _, row in validation_data.iterrows():\n r, grp, prm = row['row'], str(row['group']).strip(), str(row['param']).strip()\n \n try:\n # Filter by category\n cat_df = df[df[category_col] == grp]\n \n # Try alternative matching if no exact match\n if len(cat_df) == 0 and ':' in grp:\n cat_df = df[df[category_col].astype(str).str.contains(grp, na=False, regex=False)]\n \n total = len(cat_df)\n \n # Get column and calculate metrics\n col = get_best_column(df, prm, cat_df)\n \n if col and col in cat_df.columns:\n valid_df = cat_df[cat_df[col].notna() & ~cat_df[col].isin([0, 0.0, \"0\", \"0.0\", \"0,0\"])]\n filled = len(valid_df)\n fill_pct = filled / total if total > 0 else 0\n unique_cnt = valid_df[col].nunique()\n unique_vals = valid_df[col].unique()[:10]\n unique_str = \", \".join(map(str, unique_vals))\n if len(unique_vals) > 10:\n unique_str += f\"... ({valid_df[col].nunique()} total)\"\n else:\n filled = fill_pct = unique_cnt = 0\n unique_str = \"\"\n \n # Write to Excel\n ws[f'D{r}'] = total\n ws[f'D{r}'].alignment = Alignment(horizontal='center')\n \n ws[f'E{r}'].value = fill_pct\n ws[f'E{r}'].number_format = '0.00%'\n ws[f'E{r}'].alignment = Alignment(horizontal='center')\n ws[f'E{r}'].fill = green_fill if fill_pct > 0 else red_fill\n \n ws[f'F{r}'] = unique_cnt\n ws[f'F{r}'].alignment = Alignment(horizontal='center')\n \n ws[f'G{r}'] = unique_str\n ws[f'G{r}'].alignment = Alignment(horizontal='left')\n \n except Exception as e:\n print(f\" ERROR: {type(e).__name__}: {str(e)}\")\n ws[f'D{r}'] = 0\n ws[f'E{r}'].value = 0\n ws[f'E{r}'].fill = red_fill\n ws[f'F{r}'] = 0\n ws[f'G{r}'] = f\"ERROR: {str(e)}\"\n\n# Save to bytes & return to n8n\nwith BytesIO() as out_stream:\n wb.save(out_stream)\n out_stream.seek(0)\n result_b64 = base64.b64encode(out_stream.read()).decode()\n\noutput_timestamped = f\"DDC_Revit_IFC_Validation__{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx\"\n\n# Use the same directory as the validation rules file\nfull_output_path = os.path.join(output_directory, output_timestamped)\n\nreturn [{\n \"json\": {\n \"filename\": output_timestamped,\n \"full_path\": full_output_path\n },\n \"binary\": {\n \"data\": {\n \"data\": result_b64,\n \"fileName\": output_timestamped,\n \"fileExtension\": \"xlsx\",\n \"mimeType\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n }\n }\n}]\n"
},
"typeVersion": 2
},
{
"id": "1d601482-2b90-4d52-91b7-4e7579a88db2",
"name": "Sticky Note - Validation",
"type": "n8n-nodes-base.stickyNote",
"position": [
2560,
48
],
"parameters": {
"width": 620,
"height": 596,
"content": "## \ud83e\udd16 AUTOMATED VALIDATION\n\nProcessing includes:\n- Project data analysis\n- Rules-based checking\n- Report creation with color coding\n\n\ud83d\udfe9 Green = data present\n\ud83d\udfe5 Red = data missing"
},
"typeVersion": 1
},
{
"id": "fde712a8-5bb1-4604-bc51-0c635fbc4c0a",
"name": "Sticky Note - Conversion",
"type": "n8n-nodes-base.stickyNote",
"position": [
976,
48
],
"parameters": {
"width": 1320,
"height": 596,
"content": "## \ud83d\udd04 CONVERSION\n\nAutomatic conversion Project files \u2192 Excel\n\nIf file already exists, conversion is skipped"
},
"typeVersion": 1
},
{
"id": "8c98aae6-074a-4701-99d9-7c49ae13e682",
"name": "Sticky Note - Save & Open",
"type": "n8n-nodes-base.stickyNote",
"position": [
3200,
48
],
"parameters": {
"color": 6,
"width": 420,
"height": 596,
"content": "## \ud83d\udcc2 SAVE & OPEN\n\n\u2705 Report saved automatically\n\u2705 Excel opens for viewing\n\nFilename includes date and time"
},
"typeVersion": 1
},
{
"id": "6fce729b-f210-407e-9de2-81a193715ca5",
"name": "Save Validation Report1",
"type": "n8n-nodes-base.writeBinaryFile",
"position": [
3280,
288
],
"parameters": {
"options": {},
"fileName": "={{ $json.full_path }}"
},
"typeVersion": 1
},
{
"id": "8d09f3bc-8478-48a5-a235-460597226737",
"name": "Open Excel Report1",
"type": "n8n-nodes-base.executeCommand",
"position": [
3488,
288
],
"parameters": {
"command": "=start \"\" \"{{ $json.full_path }}\""
},
"typeVersion": 1
},
{
"id": "c70924fa-ecbc-48bb-b66c-98afe5947994",
"name": "Create - Excel filename",
"type": "n8n-nodes-base.set",
"position": [
1024,
272
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "xlsx-filename-id",
"name": "xlsx_filename",
"type": "string",
"value": "={{ $json[\"project_file\"].slice(0, -4) + \"_rvt.xlsx\" }}"
},
{
"id": "path-to-converter-pass",
"name": "path_to_converter",
"type": "string",
"value": "={{ $json[\"path_to_converter\"] }}"
},
{
"id": "project-file-pass",
"name": "project_file",
"type": "string",
"value": "={{ $json[\"project_file\"] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "2f4617b8-f146-4fd6-bee2-020a8609a92c",
"name": "Check - Does Excel file exist?",
"type": "n8n-nodes-base.readBinaryFile",
"position": [
1216,
272
],
"parameters": {
"filePath": "={{ $json[\"xlsx_filename\"] }}"
},
"typeVersion": 1,
"continueOnFail": true,
"alwaysOutputData": true
},
{
"id": "aa925149-5394-4db4-bdc2-9116f9b76700",
"name": "If - File exists?",
"type": "n8n-nodes-base.if",
"position": [
1376,
272
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "e7fb1577-e753-43f5-9f5a-4d5285aeb96e",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $binary.data ? true : false }}",
"rightValue": "={{ true }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "18206815-fe18-4e53-970d-85d7dda0d8c0",
"name": "Extract - Run converter",
"type": "n8n-nodes-base.executeCommand",
"position": [
1600,
368
],
"parameters": {
"command": "=\"{{$node[\"Setup - Define file paths\"].json[\"path_to_converter\"]}}\" \"{{$node[\"Setup - Define file paths\"].json[\"project_file\"]}}\""
},
"typeVersion": 1,
"continueOnFail": true
},
{
"id": "c701d878-85d1-4122-b5cb-59c1edc2f835",
"name": "Info - Skip conversion",
"type": "n8n-nodes-base.set",
"position": [
1680,
192
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "status-id",
"name": "status",
"type": "string",
"value": "File already exists - skipping conversion"
},
{
"id": "xlsx-filename-id",
"name": "xlsx_filename",
"type": "string",
"value": "={{ $node[\"Create - Excel filename\"].json[\"xlsx_filename\"] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "026e9414-30a8-4e99-bb9f-c91cddb8dbce",
"name": "Check - Did extraction succeed?",
"type": "n8n-nodes-base.if",
"position": [
1760,
368
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "condition1",
"operator": {
"type": "object",
"operation": "exists",
"rightType": "any"
},
"leftValue": "={{ $node[\"Extract - Run converter\"].json.error }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "362d1574-f7e0-4c7c-a0f2-27496d62cf16",
"name": "Error - Show what went wrong",
"type": "n8n-nodes-base.set",
"position": [
1920,
288
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "error-message-id",
"name": "error_message",
"type": "string",
"value": "=Extraction failed: {{ $node[\"Extract - Run converter\"].json.error || \"Unknown error\" }}"
},
{
"id": "error-code-id",
"name": "error_code",
"type": "number",
"value": "={{ $node[\"Extract - Run converter\"].json.code || -1 }}"
},
{
"id": "xlsx-filename-error",
"name": "xlsx_filename",
"type": "string",
"value": "={{ $node[\"Create - Excel filename\"].json[\"xlsx_filename\"] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "c8f21f46-0647-4819-ae0e-419d9a46f206",
"name": "Set xlsx_filename after success",
"type": "n8n-nodes-base.set",
"position": [
1920,
448
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "xlsx-filename-success",
"name": "xlsx_filename",
"type": "string",
"value": "={{ $node[\"Create - Excel filename\"].json[\"xlsx_filename\"] }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "b502d5d2-8530-427e-9390-7c11012bd06a",
"name": "Merge - Continue workflow",
"type": "n8n-nodes-base.merge",
"position": [
2160,
208
],
"parameters": {},
"typeVersion": 3
},
{
"id": "b236040c-8651-41dd-a6b1-63da8db3d4cd",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
976,
672
],
"parameters": {
"width": 540,
"height": 300,
"content": "## \u26a0\ufe0f Troubleshooting\nIf you encounter errors during conversion, be sure to reference the executable inside the **`datadrivenlibs`** folder. Use this path:\n\n```text\n\"DDC_Exporter_XXXXXXX\\datadrivenlibs\\RvtExporter.exe\"\n```\ninstead of:\n```text\n\"DDC_Exporter_XXXXXXX\\RvtExporter.exe\"\n```"
},
"typeVersion": 1
},
{
"id": "cae2d3e4-07de-45c9-9b45-da19789cabb4",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
2576,
672
],
"parameters": {
"width": 620,
"height": 268,
"content": "## \u26a0\ufe0f Troubleshooting\nIn n8n versions 1.98.0\u20131.101.x, the Python Code node (Pyodide) completely blocks the `os` module, causing this error:\n\n### \u2705 Solution \nTo avoid this error, **use latest n8n version 1.97** where the `os` module is not blocked. \nYou can launch it with the following command:\n\n```bash\nnpx n8n@latest\n```"
},
"typeVersion": 1
},
{
"id": "079841ea-bc60-47c7-ab3c-a7e9d3e59d2c",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
3280,
-80
],
"parameters": {
"width": 340,
"height": 116,
"content": "\u2b50 **If you find our tools helpful**, please **consider starring our repository** on [GitHub](https://github.com/datadrivenconstruction/cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto). \n\nYour support helps us improve and continue developing open solutions for the community!\n"
},
"typeVersion": 1
},
{
"id": "389526e6-34a8-4cb2-bb68-c9cfd28ed566",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
736,
-288
],
"parameters": {
"color": 4,
"width": 224,
"height": 176,
"content": "## \u2b07\ufe0f Only modify the variables here \n\u2014 everything else works automatically"
},
"typeVersion": 1
},
{
"id": "c41d11fb-f654-49e9-a2f0-ac81a01eff02",
"name": "Sticky Note - Settings",
"type": "n8n-nodes-base.stickyNote",
"position": [
736,
-96
],
"parameters": {
"color": 4,
"width": 220,
"height": 628,
"content": "## \u2699\ufe0f SETTINGS\n\n**Update file paths here:**\n- `path_to_converter` - path to converter\n- `project_file` - path to your project file (IFC/DWG/RVT)"
},
"typeVersion": 1
},
{
"id": "730b1426-7b20-4eb0-8f1e-b70ae0bd9fed",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2320,
-336
],
"parameters": {
"color": 4,
"width": 224,
"height": 176,
"content": "## \u2b07\ufe0f Only modify the variables here \n\u2014 everything else works automatically"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "3f498ad6-c521-472a-a619-d6b1ccc418e5",
"connections": {
"If - File exists?": {
"main": [
[
{
"node": "Info - Skip conversion",
"type": "main",
"index": 0
}
],
[
{
"node": "Extract - Run converter",
"type": "main",
"index": 0
}
]
]
},
"Merge Excel Files": {
"main": [
[
{
"node": "Validate - Enhanced",
"type": "main",
"index": 0
}
]
]
},
"Validate - Enhanced": {
"main": [
[
{
"node": "Save Validation Report1",
"type": "main",
"index": 0
}
]
]
},
"Info - Skip conversion": {
"main": [
[
{
"node": "Merge - Continue workflow",
"type": "main",
"index": 0
}
]
]
},
"Start - Click to begin": {
"main": [
[
{
"node": "Setup - Define file paths",
"type": "main",
"index": 0
}
]
]
},
"Create - Excel filename": {
"main": [
[
{
"node": "Check - Does Excel file exist?",
"type": "main",
"index": 0
}
]
]
},
"Extract - Run converter": {
"main": [
[
{
"node": "Check - Did extraction succeed?",
"type": "main",
"index": 0
}
]
]
},
"Read Project Excel File": {
"main": [
[
{
"node": "Merge Excel Files",
"type": "main",
"index": 0
}
]
]
},
"Save Validation Report1": {
"main": [
[
{
"node": "Open Excel Report1",
"type": "main",
"index": 0
}
]
]
},
"Merge - Continue workflow": {
"main": [
[
{
"node": "Read Project Excel File",
"type": "main",
"index": 0
},
{
"node": "Set Validation Rules Path",
"type": "main",
"index": 0
}
]
]
},
"Set Validation Rules Path": {
"main": [
[
{
"node": "Read Validation Rules File",
"type": "main",
"index": 0
}
]
]
},
"Setup - Define file paths": {
"main": [
[
{
"node": "Create - Excel filename",
"type": "main",
"index": 0
}
]
]
},
"Read Validation Rules File": {
"main": [
[
{
"node": "Merge Excel Files",
"type": "main",
"index": 1
}
]
]
},
"Error - Show what went wrong": {
"main": [
[
{
"node": "Merge - Continue workflow",
"type": "main",
"index": 1
}
]
]
},
"Check - Does Excel file exist?": {
"main": [
[
{
"node": "If - File exists?",
"type": "main",
"index": 0
}
]
]
},
"Check - Did extraction succeed?": {
"main": [
[
{
"node": "Error - Show what went wrong",
"type": "main",
"index": 0
}
],
[
{
"node": "Set xlsx_filename after success",
"type": "main",
"index": 0
}
]
]
},
"Set xlsx_filename after success": {
"main": [
[
{
"node": "Merge - Continue workflow",
"type": "main",
"index": 1
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Source: https://n8n.io/workflows/5868/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
A minimal workflow to convert a Revit/IFC/DWG project into analysis-ready XLSX (and optional DAE) with a single run. Set two variables, execute, and the converter does the rest. Inputs: and (RVT/IFC/D
Batch-convert CAD/BIM files to analysis-ready XLSX and optional DAE with automatic verification and a clean HTML report. Runs locally via and PowerShell on Windows.
A modular schema checker that returns detailed error messages on validation failure.
Execute Multiple Command Lines Based On Text File Inputs. Uses manualTrigger, readBinaryFile, moveBinaryData, executeCommand. Event-driven trigger; 7 nodes.
Horror Story - Template Selection. Uses executeCommand, readBinaryFile. Event-driven trigger; 6 nodes.