0.0.2 • Published 6 months ago

@opens/docgen v0.0.2

Weekly downloads
-
License
MIT
Repository
bitbucket
Last release
6 months ago

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.

0.0.2

6 months ago

0.0.1

6 months ago

0.0.0

6 months ago