npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@opens/docgen

v0.0.2

Published

A library for generating documents in various formats such as PDF, Excel, and CSV.

Readme

Docgen

Uma biblioteca TypeScript para geração de documentos em vários formatos como PDF, Excel e CSV.

MIT License

Instalação

npm install @opens/docgen

ou

yarn add @opens/docgen

Recursos

  • Geração de documentos em formatos:
    • PDF
    • Excel
    • CSV
  • Criação de tabelas com dados estruturados
  • Customização de estilo e formatação
  • Suporte para streaming para processamento eficiente de grandes volumes de dados
  • Integração com serviços de armazenamento como Amazon S3

Como Usar

Importação

import { 
  DocumentGenerator, 
  DocumentTable, 
  DocumentFormat 
} from '@opens/docgen';

Exemplo Básico

import { createWriteStream } from 'fs';
import { 
  DocumentGenerator, 
  DocumentTable, 
  DocumentFormat,
  ColumnDefinition
} from '@opens/docgen';

// Função geradora que produz os elementos do documento
function* relatorioVendasGenerator() {
  // Definição das colunas para nossa tabela
  const columns: ColumnDefinition[] = [
    { field: 'produto', header: 'Produto' },
    { field: 'quantidade', header: 'Quantidade' },
    { field: 'valorUnitario', header: 'Valor Unitário (R$)' },
    { field: 'valorTotal', header: 'Valor Total (R$)' },
    { field: 'data', header: 'Data da Venda' }
  ];

  // Dados de exemplo para a tabela
  const dadosVendas = [
    { 
      produto: 'Notebook Dell XPS 13', 
      quantidade: 5, 
      valorUnitario: 8500.00, 
      valorTotal: 42500.00, 
      data: '15/01/2025'
    },
    { 
      produto: 'Monitor LG Ultrawide', 
      quantidade: 8, 
      valorUnitario: 2200.00, 
      valorTotal: 17600.00, 
      data: '22/01/2025'
    },
    { 
      produto: 'Teclado Mecânico Logitech', 
      quantidade: 12, 
      valorUnitario: 450.00, 
      valorTotal: 5400.00, 
      data: '07/02/2025'
    },
    { 
      produto: 'Mouse sem fio Logitech', 
      quantidade: 15, 
      valorUnitario: 180.00, 
      valorTotal: 2700.00, 
      data: '14/02/2025'
    },
    { 
      produto: 'Headset HyperX', 
      quantidade: 10, 
      valorUnitario: 350.00, 
      valorTotal: 3500.00, 
      data: '28/02/2025'
    }
  ];

  // Criação do elemento de tabela com os dados e configurações
  const tabelaVendas = new DocumentTable({
    columns,
    data: dadosVendas,
    header: true,
    title: 'Vendas do Primeiro Trimestre de 2025',
    footer: 'Relatório gerado automaticamente em ' + new Date().toLocaleDateString('pt-BR')
  });

  // Retorna o elemento para o gerador de documentos
  yield tabelaVendas;
}

// Função principal para gerar o relatório
async function gerarRelatorioDeVendas() {
  try {
    // Cria um stream para o arquivo de saída
    const outputStream = createWriteStream('./relatorio-vendas.pdf');

    // Configura o formato do documento
    const config = {
      format: DocumentFormat.PDF,
    };

    // Instancia o gerador de documentos
    const generator = new DocumentGenerator(config, outputStream);

    // Gera o documento utilizando nossa função geradora
    await generator.generate(relatorioVendasGenerator);

    console.log('Relatório de vendas gerado com sucesso!');
  } catch (error) {
    console.error('Erro ao gerar relatório:', error);
  }
}

Integração com Amazon S3

Enviando documentos diretamente para o S3

import { PassThrough } from 'stream';
import { S3Client, Upload } from '@aws-sdk/client-s3';
import { 
  DocumentGenerator, 
  DocumentTable, 
  DocumentFormat
} from '@opens/docgen';

function* relatorioFuncionariosGenerator() {
  // Definir colunas e dados
  const columns = [
    { field: 'nome', header: 'Nome' },
    { field: 'departamento', header: 'Departamento' },
    { field: 'cargo', header: 'Cargo' }
  ];

  const funcionarios = [
    { nome: 'Ana Silva', departamento: 'Vendas', cargo: 'Gerente Regional' },
    { nome: 'Carlos Mendes', departamento: 'TI', cargo: 'Desenvolvedor Sênior' },
    { nome: 'Juliana Costa', departamento: 'Marketing', cargo: 'Analista de Mídias Sociais' }
  ];

  // Criar tabela
  const tabela = new DocumentTable({
    columns,
    data: funcionarios,
    header: true,
    title: 'Relatório de Funcionários',
    footer: 'Gerado em ' + new Date().toLocaleDateString('pt-BR')
  });

  yield tabela;
}

async function gerarEEnviarParaS3() {
  try {
    // Configuração do cliente S3
    const s3Client = new S3Client({
      region: 'sa-east-1',
      credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || ''
      }
    });

    // Criação de um stream de passagem (passthrough)
    const passThrough = new PassThrough();

    // Configurar o upload para o S3 (iniciará automaticamente quando dados forem escritos)
    const uploadParams = {
      Bucket: 'minha-empresa-relatorios',
      Key: `relatorio-funcionarios-${Date.now()}.pdf`,
      Body: passThrough,
      ContentType: 'application/pdf'
    };

    // Iniciar o upload
    const uploadPromise = new Upload({
      client: s3Client,
      params: uploadParams
    }).done();

    // Configurar o gerador de documentos com o stream de passagem
    const generator = new DocumentGenerator({
      format: DocumentFormat.PDF,
      options: {
        orientation: 'portrait',
        title: 'Relatório para S3'
      }
    }, passThrough);

    // Gerar documento (os dados fluirão automaticamente para o S3 via passthrough)
    await generator.generate(relatorioFuncionariosGenerator);

    // Aguardar até que o upload seja concluído
    const uploadResult = await uploadPromise;
    console.log('Documento enviado com sucesso para o S3:', uploadResult);
    return uploadResult;
  } catch (error) {
    console.error('Erro ao enviar para o S3:', error);
    throw error;
  }
}

Geração de Diferentes Formatos

PDF

const pdfConfig = {
  format: DocumentFormat.PDF,
  options: {
    orientation: 'portrait'
  }
};

Excel

const excelConfig = {
  format: DocumentFormat.EXCEL,
  options: {
    sheetName: 'Dados',
  }
};

CSV

const csvConfig = {
  format: DocumentFormat.CSV,
  options: {
    filename: 'relatorio.csv'
  }
};

Parâmetro Header nas Tabelas

O parâmetro header nas tabelas é utilizado para controlar a exibição do cabeçalho:

// Com cabeçalho (default)
const tableWithHeader = new DocumentTable({
  columns,
  data,
  header: true // Irá incluir o cabeçalho da tabela
});

// Sem cabeçalho - útil quando adicionando múltiplas tabelas que formam uma só
const tableWithoutHeader = new DocumentTable({
  columns,
  data,
  header: false // Não incluirá o cabeçalho, apenas os dados
});

Quando utilizado como false, o cabeçalho da tabela não será incluído, o que é útil em cenários onde:

  • Você está adicionando múltiplas tabelas que representam partes de uma mesma tabela lógica
  • Você deseja adicionar dados a uma tabela existente sem repetir o cabeçalho

Trabalhando com Streaming

Para arquivos grandes ou geração sob demanda:

import { createWriteStream } from 'fs';
import { DocumentGenerator, DocumentTable, DocumentFormat } from '@opens/docgen';

async function* relatorioStreamingGenerator() {
  // Definição de colunas
  const yourColumns = [
    { field: 'id', header: 'ID' },
    { field: 'nome', header: 'Nome' },
    { field: 'valor', header: 'Valor (R$)' },
    { field: 'data', header: 'Data de Registro' }
  ];
  
  // Simulação de busca de dados em lotes
  const batchSize = 100;
  for (let i = 0; i < 1000; i += batchSize) {
    const rows = await fetchDataBatch(i, batchSize); // Função fictícia para buscar dados
    
    // Primeira parte com cabeçalho
    if (i === 0) {
      const tableWithHeader = new DocumentTable({
        columns: yourColumns,
        data: rows,
        header: true, // Primeira parte inclui cabeçalho
        title: 'Relatório de Dados em Streaming',
      });
      yield tableWithHeader;
    } else {
      // Partes subsequentes sem cabeçalho
      const tableWithoutHeader = new DocumentTable({
        columns: yourColumns,
        data: rows,
        header: false // Partes subsequentes não incluem cabeçalho
      });
      yield tableWithoutHeader;
    }
  }
}

async function gerarRelatorioStreaming() {
  try {
    const outputStream = createWriteStream('./relatorio-streaming.pdf');
    
    const generator = new DocumentGenerator({
      format: DocumentFormat.PDF,
      options: {
        orientation: 'landscape',
        title: 'Relatório de Dados em Lotes'
      }
    }, outputStream);
    
    await generator.generate(relatorioStreamingGenerator);
    
    console.log('Relatório em streaming gerado com sucesso!');
  } catch (error) {
    console.error('Erro ao gerar relatório em streaming:', error);
  }
}

Tipos Disponíveis

A biblioteca exporta vários tipos úteis:

import {
  // Tipos principais
  ColumnDefinition,
  DocumentConfiguration,
  BaseElement,
  ElementType,
  DocumentFormat,
  
  // Tipos para estilos
  ElementStyling,
  TextAlignment,
  PageOrientation,
  
  // Configurações específicas para formatos
  PDFDocumentSettings,
  ExcelDocumentSettings,
  CSVDocumentSettings,
  
  // Tipos para elementos específicos
  PDFTableElementData,
  ExcelTableElementData,
  CSVTableElementData,
} from '@opens/docgen';

Estrutura de ColumnDefinition

interface ColumnDefinition {
  field: string;    // A chave do campo nos dados
  header: string;   // O texto que aparecerá no cabeçalho
  width?: number;   // Largura opcional da coluna
}

Configurações por formato

// Configurações para PDF
interface PDFDocumentSettings {
  orientation?: PageOrientation; // 'portrait' ou 'landscape'
  title?: string;               // Título do documento
  subtitle?: string;            // Subtítulo do documento
}

// Configurações para Excel
interface ExcelDocumentSettings {
  sheetName?: string;           // Nome da planilha
}

// Configurações para CSV
interface CSVDocumentSettings {
  delimiter?: string;           // Caractere delimitador
}

Licença

Este projeto está licenciado sob a licença MIT - veja o arquivo LICENSE para mais detalhes.

Contribuições

Contribuições são bem-vindas! Sinta-se à vontade para abrir issues ou pull requests.