Claude
Skills
Sign in
Back

Report Builder

Included with Lifetime
$97 forever

Create formatted business reports with data, charts, tables, and executive summaries

document-creationreportsbusinessanalyticsdata-visualizationsummaries

What this skill does


# Report Builder

The Report Builder skill automates the creation of professional business reports with data analysis, visualizations, executive summaries, and formatted sections. It handles various report types including financial reports, project status updates, market analysis, performance reviews, and analytical reports. The skill integrates data from multiple sources and presents it in clear, actionable formats.

Generate reports in PDF, Word, or HTML formats with charts, tables, trend analysis, and key insights. Perfect for recurring reports, automated dashboards, and data-driven decision-making documentation.

## Core Workflows

### Workflow 1: Generate Executive Report
**Purpose:** Create high-level report with summary, key metrics, and recommendations

**Steps:**
1. Collect data from various sources
2. Calculate key performance indicators (KPIs)
3. Generate executive summary highlighting critical points
4. Create data visualizations (charts, graphs)
5. Add detailed sections with supporting data
6. Include recommendations and action items
7. Format with professional layout
8. Export to PDF with branding

**Implementation:**
```javascript
const PDFDocument = require('pdfkit');
const ChartJS = require('chartjs-node-canvas');
const fs = require('fs');

async function generateExecutiveReport(reportData, outputPath) {
  const doc = new PDFDocument({ margin: 50 });
  const stream = fs.createWriteStream(outputPath);
  doc.pipe(stream);

  // Cover page
  doc.fontSize(32)
     .fillColor('#2C3E50')
     .text(reportData.title, { align: 'center' })
     .moveDown()
     .fontSize(18)
     .fillColor('#7F8C8D')
     .text(reportData.subtitle, { align: 'center' })
     .moveDown(2)
     .fontSize(12)
     .text(`Reporting Period: ${reportData.period}`, { align: 'center' })
     .text(`Generated: ${new Date().toLocaleDateString()}`, { align: 'center' });

  // Company logo if provided
  if (reportData.logo) {
    doc.image(reportData.logo, doc.page.width / 2 - 50, 150, { width: 100 });
  }

  // Executive Summary
  doc.addPage();
  doc.fontSize(24)
     .fillColor('#2C3E50')
     .text('Executive Summary', { underline: true })
     .moveDown();

  doc.fontSize(11)
     .fillColor('#34495E')
     .text(reportData.executiveSummary, { align: 'justify', lineGap: 4 });

  // Key Metrics Section
  doc.moveDown(2);
  doc.fontSize(18)
     .fillColor('#2C3E50')
     .text('Key Performance Indicators');

  doc.moveDown();

  // KPI Cards (2x2 grid)
  const kpiWidth = 220;
  const kpiHeight = 100;
  const spacing = 20;

  reportData.kpis.forEach((kpi, index) => {
    const row = Math.floor(index / 2);
    const col = index % 2;
    const x = 50 + col * (kpiWidth + spacing);
    const y = doc.y + row * (kpiHeight + spacing);

    // KPI Card background
    doc.fillColor(kpi.trend === 'up' ? '#27AE60' : kpi.trend === 'down' ? '#E74C3C' : '#3498DB')
       .opacity(0.1)
       .rect(x, y, kpiWidth, kpiHeight)
       .fill();

    doc.opacity(1);

    // KPI Label
    doc.fontSize(10)
       .fillColor('#7F8C8D')
       .text(kpi.label, x + 10, y + 10, { width: kpiWidth - 20 });

    // KPI Value
    doc.fontSize(28)
       .fillColor('#2C3E50')
       .text(kpi.value, x + 10, y + 30);

    // KPI Change
    const changeColor = kpi.trend === 'up' ? '#27AE60' : kpi.trend === 'down' ? '#E74C3C' : '#7F8C8D';
    doc.fontSize(12)
       .fillColor(changeColor)
       .text(kpi.change, x + 10, y + 70);
  });

  // Adjust Y position after KPI grid
  doc.y += Math.ceil(reportData.kpis.length / 2) * (kpiHeight + spacing) + spacing;

  // Detailed Sections
  reportData.sections.forEach(async (section) => {
    doc.addPage();

    // Section Title
    doc.fontSize(20)
       .fillColor('#2C3E50')
       .text(section.title, { underline: true })
       .moveDown();

    // Section Content
    doc.fontSize(11)
       .fillColor('#34495E')
       .text(section.content, { align: 'justify', lineGap: 4 });

    // Add chart if section has data
    if (section.chartData) {
      doc.moveDown();
      const chartImage = await generateChart(section.chartData);
      doc.image(chartImage, 100, doc.y, { width: 400 });
      doc.moveDown(15); // Space for chart
    }

    // Add table if section has table data
    if (section.tableData) {
      doc.moveDown();
      addTable(doc, section.tableData);
    }
  });

  // Recommendations
  doc.addPage();
  doc.fontSize(20)
     .fillColor('#2C3E50')
     .text('Recommendations', { underline: true })
     .moveDown();

  reportData.recommendations.forEach((rec, index) => {
    doc.fontSize(11)
       .fillColor('#34495E')
       .text(`${index + 1}. ${rec}`, { lineGap: 6 });
    doc.moveDown(0.5);
  });

  // Footer on all pages
  const pages = doc.bufferedPageRange();
  for (let i = 0; i < pages.count; i++) {
    doc.switchToPage(i);
    doc.fontSize(8)
       .fillColor('#95A5A6')
       .text(
         `${reportData.company} | Confidential | Page ${i + 1} of ${pages.count}`,
         50,
         doc.page.height - 50,
         { align: 'center', width: doc.page.width - 100 }
       );
  }

  doc.end();

  return new Promise((resolve, reject) => {
    stream.on('finish', () => resolve(outputPath));
    stream.on('error', reject);
  });
}

async function generateChart(chartData) {
  const chartCanvas = new ChartJS.ChartJSNodeCanvas({ width: 800, height: 400 });

  const configuration = {
    type: chartData.type || 'bar',
    data: {
      labels: chartData.labels,
      datasets: [{
        label: chartData.label,
        data: chartData.values,
        backgroundColor: chartData.colors || '#3498DB',
        borderColor: '#2C3E50',
        borderWidth: 1
      }]
    },
    options: {
      responsive: true,
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
  };

  return await chartCanvas.renderToBuffer(configuration);
}

function addTable(doc, tableData) {
  const tableTop = doc.y;
  const cellPadding = 8;
  const rowHeight = 25;
  const colWidth = (doc.page.width - 100) / tableData.headers.length;

  // Header row
  doc.fillColor('#34495E')
     .rect(50, tableTop, doc.page.width - 100, rowHeight)
     .fill();

  doc.fillColor('#FFFFFF')
     .fontSize(10);

  tableData.headers.forEach((header, i) => {
    doc.text(header, 50 + i * colWidth + cellPadding, tableTop + cellPadding, {
      width: colWidth - cellPadding * 2
    });
  });

  // Data rows
  doc.fillColor('#34495E');

  tableData.rows.forEach((row, rowIndex) => {
    const y = tableTop + (rowIndex + 1) * rowHeight;

    // Alternate row colors
    if (rowIndex % 2 === 1) {
      doc.fillColor('#F8F9FA')
         .rect(50, y, doc.page.width - 100, rowHeight)
         .fill();
    }

    doc.fillColor('#2C3E50');

    row.forEach((cell, cellIndex) => {
      doc.text(cell, 50 + cellIndex * colWidth + cellPadding, y + cellPadding, {
        width: colWidth - cellPadding * 2
      });
    });
  });

  doc.y = tableTop + (tableData.rows.length + 1) * rowHeight + 10;
}
```

### Workflow 2: Monthly Performance Report
**Purpose:** Automated monthly report with metrics, trends, and comparisons

**Steps:**
1. Query data for current month and previous periods
2. Calculate month-over-month and year-over-year changes
3. Generate trend charts
4. Identify top performers and areas of concern
5. Create comparison tables
6. Add narrative insights based on data patterns
7. Format and distribute report

**Implementation:**
```javascript
async function generateMonthlyReport(month, year, dataSource) {
  // Fetch data
  const currentData = await dataSource.getMonthData(month, year);
  const previousMonthData = await dataSource.getMonthData(month - 1, year);
  const lastYearData = await dataSource.getMonthData(month, year - 1);

  // Calculate metrics
  const metrics = {
    revenue: {
      current: currentData.revenue,
      momChange: calculatePercentChange(currentData.revenue, previousMonthData.revenue),
      yoyChange: calculatePercentChange(currentData.revenue, l

Related in document-creation