Реалізація експорту графіків/дашбордів у PDF/PNG на сайті

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація експорту графіків/дашбордів у PDF/PNG на сайті
Середня
від 1 робочого дня до 3 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація експорту графіків/дашбордів у PDF/PNG для веб-сайтів

Експорт дашборда у PDF або PNG потребує захвату DOM-елементів як зображень та генерування документа. Існує два підходи: клієнтський (через HTML Canvas API) та серверний (через headless Chromium).

Клієнтський експорт: html2canvas + jsPDF

npm install html2canvas jspdf
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';

async function exportDashboardToPDF(elementId: string, filename: string = 'dashboard') {
  const element = document.getElementById(elementId);
  if (!element) return;

  const loader = document.createElement('div');
  loader.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.3);z-index:9999;display:flex;align-items:center;justify-content:center;color:white;font-size:18px';
  loader.textContent = 'Генерація PDF...';
  document.body.appendChild(loader);

  try {
    const canvas = await html2canvas(element, {
      scale: 2,
      useCORS: true,
      logging: false,
      backgroundColor: '#ffffff'
    });

    const imgData = canvas.toDataURL('image/png');
    const pdf = new jsPDF({
      orientation: canvas.width > canvas.height ? 'landscape' : 'portrait',
      unit: 'px',
      format: [canvas.width / 2, canvas.height / 2]
    });

    pdf.addImage(imgData, 'PNG', 0, 0, canvas.width / 2, canvas.height / 2);
    pdf.save(`${filename}_${format(new Date(), 'yyyy-MM-dd')}.pdf`);

  } finally {
    document.body.removeChild(loader);
  }
}

async function exportToPNG(elementId: string, filename: string = 'chart') {
  const element = document.getElementById(elementId);
  if (!element) return;

  const canvas = await html2canvas(element, { scale: 2, backgroundColor: '#ffffff' });

  const link = document.createElement('a');
  link.download = `${filename}_${format(new Date(), 'yyyy-MM-dd')}.png`;
  link.href = canvas.toDataURL('image/png');
  link.click();
}

React Hook

function useExport(elementRef: React.RefObject<HTMLElement>) {
  const [isExporting, setIsExporting] = useState(false);

  const exportToPDF = async (filename?: string) => {
    if (!elementRef.current || isExporting) return;
    setIsExporting(true);

    try {
      await exportDashboardToPDF(elementRef.current, filename);
    } finally {
      setIsExporting(false);
    }
  };

  const exportToPNG = async (filename?: string) => {
    if (!elementRef.current || isExporting) return;
    setIsExporting(true);

    try {
      const canvas = await html2canvas(elementRef.current, {
        scale: 2, backgroundColor: '#ffffff'
      });
      downloadCanvas(canvas, filename);
    } finally {
      setIsExporting(false);
    }
  };

  return { exportToPDF, exportToPNG, isExporting };
}

function DashboardWithExport() {
  const dashboardRef = useRef<HTMLDivElement>(null);
  const { exportToPDF, exportToPNG, isExporting } = useExport(dashboardRef);

  return (
    <div>
      <div className="flex gap-2 mb-4">
        <button onClick={() => exportToPDF('analytics-report')}
          disabled={isExporting} className="export-btn">
          {isExporting ? '⏳' : '📄'} Експорт PDF
        </button>
        <button onClick={() => exportToPNG('dashboard')}
          disabled={isExporting} className="export-btn">
          {isExporting ? '⏳' : '🖼'} Зберегти PNG
        </button>
      </div>

      <div ref={dashboardRef} id="dashboard-content">
        <Charts />
      </div>
    </div>
  );
}

Серверний експорт через Puppeteer

Для складних дашбордів із SVG/WebGL графіками html2canvas може не справитися. Серверний рендер:

import puppeteer from 'puppeteer';

app.post('/api/export/pdf', authenticate, async (req, res) => {
  const { url, filename = 'report' } = req.body;

  const browser = await puppeteer.launch({ headless: 'new' });
  const page = await browser.newPage();

  await page.setCookie({
    name: 'auth_token',
    value: req.token,
    domain: 'your-app.com'
  });

  await page.goto(`${process.env.APP_URL}${url}?export=true`, {
    waitUntil: 'networkidle0',
    timeout: 30000
  });

  await page.waitForSelector('[data-loaded="true"]', { timeout: 15000 });

  const pdf = await page.pdf({
    format: 'A4',
    landscape: true,
    printBackground: true,
    margin: { top: '20mm', right: '15mm', bottom: '20mm', left: '15mm' }
  });

  await browser.close();

  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', `attachment; filename="${filename}.pdf"`);
  res.send(pdf);
});

Експорт даних у CSV/Excel

import * as XLSX from 'xlsx';

function exportToExcel(data: Record<string, unknown>[], filename: string) {
  const worksheet = XLSX.utils.json_to_sheet(data);
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, worksheet, 'Data');
  XLSX.writeFile(workbook, `${filename}.xlsx`);
}

Часові межи

Клієнтський експорт PNG/PDF + кнопки — 1–2 дні. Серверний через Puppeteer — 3–5 днів.