| name | docx-construction |
| description | Word document generation for construction: contracts, proposals, reports, specifications, transmittals. Template-based with dynamic content insertion. |
| homepage | https://datadrivenconstruction.io |
| metadata | {"openclaw":{"emoji":"📄","os":["darwin","linux","win32"],"homepage":"https://datadrivenconstruction.io","requires":{"bins":"[Truncated]"}}} |
Word Document Generation for Construction
Overview
Create professional Word documents for construction workflows using python-docx. Generate contracts, proposals, reports, and specifications from templates with dynamic data.
Construction Use Cases
1. Contract Generation
Generate construction contracts from templates with project-specific data.
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
from datetime import datetime
def generate_subcontract(template_path: str, contract_data: dict, output_path: str) -> str:
"""Generate subcontract from template."""
doc = Document(template_path)
replacements = {
'{{PROJECT_NAME}}': contract_data['project_name'],
'{{CONTRACT_NUMBER}}': contract_data['contract_number'],
'{{SUBCONTRACTOR_NAME}}': contract_data['subcontractor'],
'{{SCOPE_OF_WORK}}': contract_data['scope'],
'{{CONTRACT_VALUE}}': f"${contract_data['value']:,.2f}",
'{{START_DATE}}': contract_data['start_date'],
'{{END_DATE}}': contract_data['end_date'],
'{{RETENTION_PERCENT}}': f"{contract_data['retention']}%",
}
for paragraph in doc.paragraphs:
for key, value in replacements.items():
if key in paragraph.text:
paragraph.text = paragraph.text.replace(key, value)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for key, value in replacements.items():
if key in cell.text:
cell.text = cell.text.replace(key, value)
doc.save(output_path)
return output_path
2. Proposal Document
Create professional project proposals.
def create_proposal(project_info: dict, scope_items: list, pricing: dict) -> Document:
"""Create construction proposal document."""
doc = Document()
title = doc.add_heading('Project Proposal', 0)
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
doc.add_heading('Project Information', level=1)
doc.add_paragraph(f"Project: {project_info['name']}")
doc.add_paragraph(f"Location: {project_info['location']}")
doc.add_paragraph(f"Client: {project_info['client']}")
doc.add_paragraph(f"Date: {datetime.now().strftime('%B %d, %Y')}")
doc.add_heading('Scope of Work', level=1)
for item in scope_items:
doc.add_paragraph(item, style='List Bullet')
doc.add_heading('Pricing Summary', level=1)
table = doc.add_table(rows=1, cols=3)
table.style = 'Table Grid'
headers = table.rows[0].cells
headers[0].text = 'Description'
headers[1].text = 'Quantity'
headers[2].text = 'Amount'
item pricing[]:
row = table.add_row().cells
row[].text = item[]
row[].text = (item[])
row[].text =
total_row = table.add_row().cells
total_row[].text =
total_row[].text =
doc.add_heading(, level=)
doc.add_paragraph()
doc.add_paragraph()
doc
3. Daily Report Generation
Generate daily construction reports.
def generate_daily_report(report_data: dict, output_path: str) -> str:
"""Generate daily construction report."""
doc = Document()
doc.add_heading(f"Daily Construction Report", 0)
doc.add_paragraph(f"Project: {report_data['project_name']}")
doc.add_paragraph(f"Date: {report_data['date']}")
doc.add_paragraph(f"Report #: {report_data['report_number']}")
doc.add_paragraph(f"Weather: {report_data['weather']}")
doc.add_heading('Workforce On-Site', level=1)
workforce_table = doc.add_table(rows=1, cols=3)
workforce_table.style = 'Table Grid'
headers = workforce_table.rows[0].cells
headers[0].text = 'Trade'
headers[1].text = 'Company'
headers[2].text = 'Headcount'
for crew in report_data['workforce']:
row = workforce_table.add_row().cells
row[0].text = crew['trade']
row[1].text = crew['company']
row[2].text = str(crew['count'])
doc.add_heading(, level=)
item report_data[]:
doc.add_paragraph()
report_data.get():
doc.add_heading(, level=)
issue report_data[]:
p = doc.add_paragraph()
p.add_run().bold =
p.add_run(issue[])
doc.add_heading(, level=)
doc.add_paragraph()
doc.add_paragraph()
report_data.get():
doc.add_heading(, level=)
photo report_data[]:
doc.add_picture(photo[], width=Inches())
doc.add_paragraph(photo.get(, ), style=)
doc.save(output_path)
output_path
4. Transmittal Letter
Generate transmittal documents for submittals.
def create_transmittal(transmittal_data: dict) -> Document:
"""Create transmittal letter for submittals."""
doc = Document()
doc.add_paragraph(f"Date: {transmittal_data['date']}")
doc.add_paragraph(f"Transmittal No: {transmittal_data['number']}")
doc.add_paragraph()
doc.add_paragraph(f"To: {transmittal_data['to']}")
doc.add_paragraph(f"From: {transmittal_data['from']}")
doc.add_paragraph(f"Project: {transmittal_data['project']}")
doc.add_paragraph(f"Subject: {transmittal_data['subject']}")
doc.add_paragraph()
doc.add_paragraph("We are transmitting the following:")
table = doc.add_table(rows=1, cols=4)
table.style = 'Table Grid'
headers = table.rows[0].cells
headers[0].text = 'No.'
headers[1].text = 'Description'
headers[2].text = 'Copies'
headers[3].text = 'Action'
for i, item in enumerate(transmittal_data['items'], 1):
row = table.add_row().cells
row[0].text = str(i)
row[].text = item[]
row[].text = (item.get(, ))
row[].text = item.get(, )
doc.add_paragraph()
transmittal_data.get():
doc.add_paragraph()
doc
5. Specification Section Writer
Generate specification sections.
def generate_spec_section(spec_data: dict) -> Document:
"""Generate CSI-formatted specification section."""
doc = Document()
doc.add_heading(f"SECTION {spec_data['number']}", 0)
doc.add_heading(spec_data['title'].upper(), level=1)
doc.add_heading('PART 1 - GENERAL', level=1)
doc.add_heading('1.1 SUMMARY', level=2)
doc.add_paragraph(f"A. Section includes: {spec_data['summary']}")
doc.add_heading('1.2 RELATED SECTIONS', level=2)
for section in spec_data.get('related_sections', []):
doc.add_paragraph(f"A. Section {section['number']}: {section['title']}")
doc.add_heading('1.3 SUBMITTALS', level=2)
for submittal in spec_data.get('submittals', []):
doc.add_paragraph(f"A. {submittal}")
doc.add_heading('PART 2 - PRODUCTS', level=1)
doc.add_heading('2.1 MANUFACTURERS', level=2)
for mfr in spec_data.get('manufacturers', []):
doc.add_paragraph(f"A. ")
doc.add_heading(, level=)
material spec_data.get(, []):
p = doc.add_paragraph()
prop material.get(, []):
doc.add_paragraph(, style=)
doc.add_heading(, level=)
doc.add_heading(, level=)
step spec_data.get(, []):
doc.add_paragraph()
doc.add_heading(, level=)
qc spec_data.get(, []):
doc.add_paragraph()
doc
Integration with DDC Pipeline
import pandas as pd
estimate = pd.read_excel("project_estimate.xlsx")
contract_data = {
'project_name': 'Downtown Office Tower',
'contract_number': 'SC-2026-001',
'subcontractor': 'ABC Electrical Inc.',
'scope': 'Complete electrical installation per Division 26',
'value': estimate[estimate['division'] == '26']['total'].sum(),
'start_date': '2026-03-01',
'end_date': '2026-09-30',
'retention': 10
}
generate_subcontract('templates/subcontract.docx', contract_data, 'contracts/SC-2026-001.docx')
Dependencies
pip install python-docx
Resources