Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Word document generation for construction: contracts, proposals, reports, specifications, transmittals. Template-based with dynamic content insertion.
.claude/skills/datadrivenconstruction-docx-construction/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 28% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -16% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 119% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 141% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 101% | 0% |
Create professional Word documents for construction workflows using python-docx. Generate contracts, proposals, reports, and specifications from templates with dynamic data.
Generate construction contracts from templates with project-specific data.
pythonfrom 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) # Replace placeholders 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) # Also check tables 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
Create professional project proposals.
pythondef create_proposal(project_info: dict, scope_items: list, pricing: dict) -> Document: """Create construction proposal document.""" doc = Document() # Title title = doc.add_heading('Project Proposal', 0) title.alignment = WD_ALIGN_PARAGRAPH.CENTER # Project Info 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')}") # Scope of Work doc.add_heading('Scope of Work', level=1) for item in scope_items: doc.add_paragraph(item, style='List Bullet') # Pricing Table doc.add_heading('Pricing Summary', level=1) table = doc.add_table(rows=1, cols=3) table.style = 'Table Grid' # Headers headers = table.rows[0].cells headers[0].text = 'Description' headers[1].text = 'Quantity' headers[2].text = 'Amount' # Add line items for item in pricing['line_items']: row = table.add_row().cells row[0].text = item['description'] row[1].text = str(item['quantity']) row[2].text = f"${item['amount']:,.2f}" # Total row total_row = table.add_row().cells total_row[0].text = 'TOTAL' total_row[2].text = f"${pricing['total']:,.2f}" # Terms doc.add_heading('Terms & Conditions', level=1) doc.add_paragraph(f"Payment Terms: {pricing.get('payment_terms', 'Net 30')}") doc.add_paragraph(f"Validity: {pricing.get('validity', '30 days')}") return doc
Generate daily construction reports.
pythondef generate_daily_report(report_data: dict, output_path: str) -> str: """Generate daily construction report.""" doc = Document() # Header 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']}") # Workforce 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']) # Work Completed doc.add_heading('Work Completed Today', level=1) for item in report_data['work_completed']: doc.add_paragraph(f"• {item}") # Issues/Delays if report_data.get('issues'): doc.add_heading('Issues & Delays', level=1) for issue in report_data['issues']: p = doc.add_paragraph() p.add_run(f"{issue['type']}: ").bold = True p.add_run(issue['description']) # Safety doc.add_heading('Safety', level=1) doc.add_paragraph(f"Incidents: {report_data.get('incidents', 'None')}") doc.add_paragraph(f"Near Misses: {report_data.get('near_misses', 'None')}") # Photos placeholder if report_data.get('photos'): doc.add_heading('Site Photos', level=1) for photo in report_data['photos']: doc.add_picture(photo['path'], width=Inches(5)) doc.add_paragraph(photo.get('caption', ''), style='Caption') doc.save(output_path) return output_path
Generate transmittal documents for submittals.
pythondef create_transmittal(transmittal_data: dict) -> Document: """Create transmittal letter for submittals.""" doc = Document() # Header info doc.add_paragraph(f"Date: {transmittal_data['date']}") doc.add_paragraph(f"Transmittal No: {transmittal_data['number']}") doc.add_paragraph() # To/From 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() # Items transmitted 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[1].text = item['description'] row[2].text = str(item.get('copies', 1)) row[3].text = item.get('action', 'For Review') doc.add_paragraph() # Remarks if transmittal_data.get('remarks'): doc.add_paragraph(f"Remarks: {transmittal_data['remarks']}") return doc
Generate specification sections.
pythondef generate_spec_section(spec_data: dict) -> Document: """Generate CSI-formatted specification section.""" doc = Document() # Section header doc.add_heading(f"SECTION {spec_data['number']}", 0) doc.add_heading(spec_data['title'].upper(), level=1) # Part 1 - General 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}") # Part 2 - Products 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. {mfr}") doc.add_heading('2.2 MATERIALS', level=2) for material in spec_data.get('materials', []): p = doc.add_paragraph(f"A. {material['name']}") for prop in material.get('properties', []): doc.add_paragraph(f" 1. {prop}", style='List Number') # Part 3 - Execution doc.add_heading('PART 3 - EXECUTION', level=1) doc.add_heading('3.1 INSTALLATION', level=2) for step in spec_data.get('installation', []): doc.add_paragraph(f"A. {step}") doc.add_heading('3.2 QUALITY CONTROL', level=2) for qc in spec_data.get('quality_control', []): doc.add_paragraph(f"A. {qc}") return doc
python# Example: Generate contract from estimate data import pandas as pd # Load estimate estimate = pd.read_excel("project_estimate.xlsx") # Prepare contract data 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 contract generate_subcontract('templates/subcontract.docx', contract_data, 'contracts/SC-2026-001.docx')
bashpip install python-docx
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | pass→pass | 5,833 | 2,773 | -52% | 1 | 1 | 0% | 1,061 | 3,376 | +218% | 0 | 0 | — |
case-01 | fail→fail | 13,375 | 26,871 | +101% | 1 | 1 | 0% | 2,572 | 6,010 | +134% | 0 | 0 | — |
case-02 | fail→fail | 31,080 | 26,915 | -13% | 1 | 1 | 0% | 6,217 | 9,138 | +47% | 0 | 0 | — |
case-03 | fail→fail | 27,654 | 25,985 | -6% | 1 | 1 | 0% | 6,226 | 9,148 | +47% | 0 | 0 | — |
case-04 | fail→fail | 27,843 | 27,839 | -0% | 1 | 1 | 0% | 6,181 | 9,102 | +47% | 0 | 0 | — |
case-06 | fail→pass | 18,657 | 9,075 | -51% | 1 | 1 | 0% | 3,621 | 4,638 | +28% | 0 | 0 | — |
case-07 | pass→pass | 10,896 | 4,560 | -58% | 1 | 1 | 0% | 1,885 | 3,717 | +97% | 0 | 0 | — |
case-08 | fail→fail | 18,310 | 13,934 | -24% | 1 | 1 | 0% | 3,445 | 5,611 | +63% | 0 | 0 | — |
case-09 | fail→pass | 27,747 | 10,646 | -62% | 1 | 1 | 0% | 6,183 | 5,163 | -16% | 0 | 0 | — |
case-10 | pass→fail | 14,989 | 8,188 | -45% | 1 | 1 | 0% | 2,646 | 4,438 | +68% | 0 | 0 | — |
case-11 | fail→pass | 9,479 | 3,484 | -63% | 1 | 1 | 0% | 1,639 | 3,589 | +119% | 0 | 0 | — |
case-12 | pass→pass | 11,759 | 7,673 | -35% | 1 | 1 | 0% | 1,907 | 4,295 | +125% | 0 | 0 | — |
case-13 | pass→pass | 18,602 | 17,823 | -4% | 1 | 1 | 0% | 3,154 | 6,190 | +96% | 0 | 0 | — |
case-14 | pass→pass | 11,055 | 5,569 | -50% | 1 | 1 | 0% | 2,057 | 3,891 | +89% | 0 | 0 | — |
case-15 | pass→pass | 17,900 | 16,933 | -5% | 1 | 1 | 0% | 3,338 | 6,047 | +81% | 0 | 0 | — |
case-16 | pass→pass | 8,838 | 2,073 | -77% | 1 | 1 | 0% | 1,482 | 3,224 | +118% | 0 | 0 | — |
case-17 | pass→pass | 8,862 | 3,200 | -64% | 1 | 1 | 0% | 1,521 | 3,498 | +130% | 0 | 0 | — |
case-18 | fail→pass | 7,625 | 3,298 | -57% | 1 | 1 | 0% | 1,449 | 3,496 | +141% | 0 | 0 | — |
case-19 | fail→pass | 9,182 | 2,760 | -70% | 1 | 1 | 0% | 1,678 | 3,376 | +101% | 0 | 0 | — |
case-20 | pass→pass | 5,069 | 1,742 | -66% | 1 | 1 | 0% | 759 | 3,196 | +321% | 0 | 0 | — |
case-21 | pass→pass | 9,405 | 5,053 | -46% | 1 | 1 | 0% | 1,751 | 3,774 | +116% | 0 | 0 | — |
case-22 | pass→fail | 13,563 | 16,276 | +20% | 1 | 1 | 0% | 2,716 | 6,276 | +131% | 0 | 0 | — |
case-23 | pass→pass | 10,951 | 11,751 | +7% | 1 | 1 | 0% | 2,001 | 5,204 | +160% | 0 | 0 | — |
case-24 | pass→pass | 16,243 | 16,758 | +3% | 1 | 1 | 0% | 3,257 | 6,144 | +89% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +13 percentage points is the difference between those two pass rates over the 24 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.