@sme.up/doc-alchemist
v1.8.0-SNAPSHOT-20260206155450
Published
Library for generating documents in various formats, including Excel and PDF.
Keywords
Readme
Doc Alchemist
A powerful TypeScript library for generating documents in various formats (PDF, Excel) with advanced support for data transformation, charts, and complex layouts.
Quick Start
import {
pdfmakeDocumentToPdfData,
WebupManagerData,
} from "@sme.up/doc-alchemist";
import { SmeupDataStructureType } from "@sme.up/doc-alchemist";
const webupManagerData: WebupManagerData = {
mathLocale: "it-IT",
datesLocale: "it-IT",
themeBackground: "",
};
const doc = {
content: [{ text: "Hello World", fontSize: 20, bold: true }],
};
const pdf = await pdfmakeDocumentToPdfData(doc, { webupManagerData });
await fs.writeFile("output.pdf", pdf);Installation
npm install @sme.up/doc-alchemistFeatures
- PDF Generation with pdfmake integration
- Excel Export from SmeUP data structures
- Chart Generation (line, bar, pie)
- Form Filling for existing PDFs
- Data Transformation from SmeUP formats
- Advanced Layouts with columns and boxes
PDF Generation Examples
Simple PDF from SmeUP DataTable
For quick PDF generation from a SmeUP DataTable without complex layouts, use dataTableToPdfData:
import { dataTableToPdfData } from "@sme.up/doc-alchemist";
import { SmeupDataStructureType } from "@sme.up/doc-alchemist";
const dataTable = {
type: SmeupDataStructureType.SmeupDataTable,
columns: [
{ name: "col1", title: "Product", visible: true, obj: { t: "", p: "" } },
{ name: "col2", title: "Quantity", visible: true, obj: { t: "NR", p: "" } },
{ name: "col3", title: "Price", visible: true, obj: { t: "NR", p: "" } },
],
rows: [
{
cells: {
col1: { value: "Product A", obj: { t: "", p: "", k: "Product A" } },
col2: { value: "10", obj: { t: "NR", p: "", k: "10" } },
col3: { value: "25.50", obj: { t: "NR", p: "", k: "25.50" } },
},
},
{
cells: {
col1: { value: "Product B", obj: { t: "", p: "", k: "Product B" } },
col2: { value: "5", obj: { t: "NR", p: "", k: "5" } },
col3: { value: "45.00", obj: { t: "NR", p: "", k: "45.00" } },
},
},
],
cover: {
titles: {
T01: "Sales Report",
T02: "Q4 2023",
T03: "Confidential",
},
},
};
const component = {
smeupDataTable: dataTable,
props: {},
};
const pdf = await dataTableToPdfData(component, webupManagerData);
await fs.writeFile("simple-table.pdf", pdf);Generates a PDF with automatic table formatting, cover page with title/subtitle, and built-in styling using jsPDF.
Tables from SmeUP Data
For advanced layouts and customization, use pdfmakeDocumentToPdfData:
import { pdfmakeDocumentToPdfData } from "@sme.up/doc-alchemist";
import { SmeupDataStructureType } from "@sme.up/doc-alchemist";
const dataTable = {
type: SmeupDataStructureType.SmeupDataTable,
columns: [
{ name: "col1", title: "Name" },
{ name: "col2", title: "Description" },
{ name: "col3", title: "Status" },
{ name: "col4", title: "Date", obj: { t: "D8", p: "*YYMD" } },
{ name: "col5", title: "Amount", obj: { t: "NR", p: "" } },
],
rows: [
{
cells: {
col1: { value: "Item 1" },
col2: { value: "First item description" },
col3: { value: "Active" },
col4: {
value: "2023-11-15",
obj: { t: "D8", p: "*YYMD", k: "20231115" },
},
col5: { value: "1250.50", obj: { t: "NR", p: "", k: "1250.50" } },
},
},
{
cells: {
col1: { value: "Item 2" },
col2: { value: "Second item description" },
col3: { value: "Pending" },
col4: {
value: "2023-11-20",
obj: { t: "D8", p: "*YYMD", k: "20231120" },
},
col5: { value: "3450.75", obj: { t: "NR", p: "", k: "3450.75" } },
},
},
],
};
const doc = {
content: [
{ text: "Data in SmeUP format", fontSize: 20, bold: true },
{
table: {
smeup: {
data: dataTable,
},
},
layout: "lightHorizontalLines",
},
],
};
const pdf = await pdfmakeDocumentToPdfData(doc, { webupManagerData });
await fs.writeFile("table-output.pdf", pdf);Generates a formatted table from SmeUP data structure with automatic column detection, date formatting, and number formatting.
Tables from FUN
const doc = {
content: [
{ text: "Data retrieved from FUN", fontSize: 20, bold: true },
{
table: {
smeup: {
fun: "F(EXB;SERV;MET)",
},
},
layout: "lightHorizontalLines",
},
],
};
const context = {
webupManagerData,
getSmeupDataStructure: async (fun: string) => {
// Your implementation to fetch data based on FUN
return await fetchDataFromServer(fun);
},
};
const pdf = await pdfmakeDocumentToPdfData(doc, context);
await fs.writeFile("fun-table.pdf", pdf);Dynamically retrieves data using FUN expressions and renders it as a table.
Images in PDF
const doc = {
content: [
{
table: {
body: [
["Image from URL", "Image from Object"],
[
{
stack: [
{
image: {
smeup: {
url: "https://picsum.photos/seed/picsum/200/300",
},
},
width: 200,
},
{ text: "URL-based image", margin: [0, 5, 0, 0] },
],
},
{
stack: [
{
image: {
smeup: {
obj: { t: "CN", p: "COL", k: "LANSTS" },
},
},
},
{ text: "SmeUP object image", margin: [0, 5, 0, 0] },
],
},
],
],
},
},
],
};
const pdf = await pdfmakeDocumentToPdfData(doc, {
webupManagerData,
fetchData: fetch,
damSvcEndpoint: "https://your-dam-service.com",
});
await fs.writeFile("images.pdf", pdf);Supports images from HTTP(S) URLs and SmeUP object references with automatic fetching and embedding.
Headers and Footers with Page Numbers
const doc = {
styles: {
header: { fontSize: 18, bold: true },
footer: { fontSize: 8, italics: true },
},
header: {
columns: [
{ text: "Document Title", alignment: "left", style: "header" },
{
text: "Page [CurrentPage] of [PageCount]",
alignment: "right",
fontSize: 10,
},
],
margin: [40, 20, 40, 10],
},
footer: {
columns: [
{
text: "Generated on " + new Date().toLocaleDateString(),
alignment: "left",
fontSize: 8,
},
{
text: "[CurrentPage]/[PageCount]",
alignment: "right",
fontSize: 8,
},
],
margin: [40, 10, 40, 20],
},
content: [
{ text: "This is the first page.", pageBreak: "after" },
{ text: "This is the second page", pageBreak: "after" },
{ text: "This is the third page." },
],
pageMargins: [40, 60, 40, 60],
};
const pdf = await pdfmakeDocumentToPdfData(doc, { webupManagerData });
await fs.writeFile("header-footer.pdf", pdf);Automatically replaces [CurrentPage] and [PageCount] placeholders with actual page numbers.
Custom Table Layouts
const doc = {
content: [
{ text: "Table with Custom Layout", fontSize: 20, bold: true },
{
table: {
headerRows: 1,
body: [
[
{ text: "Header 1", bold: true, fillColor: "#CCCCCC" },
{ text: "Header 2", bold: true, fillColor: "#CCCCCC" },
{ text: "Header 3", bold: true, fillColor: "#CCCCCC" },
],
["Row 1, Cell 1", "Row 1, Cell 2", "Row 1, Cell 3"],
["Row 2, Cell 1", "Row 2, Cell 2", "Row 2, Cell 3"],
["Row 3, Cell 1", "Row 3, Cell 2", "Row 3, Cell 3"],
],
},
layout: {
hLineWidth: 2,
vLineWidth: 1,
hLineColor: "#0000FF",
vLineColor: "#FF0000",
},
},
],
};
const pdf = await pdfmakeDocumentToPdfData(doc, { webupManagerData });
await fs.writeFile("custom-layout.pdf", pdf);Creates tables with custom border colors, widths, and cell styling.
Charts in PDF
import { ChartType, ChartOptions } from "@sme.up/doc-alchemist";
const doc = {
content: [
{ text: "Sales Report with Charts", fontSize: 20, bold: true },
// Line Chart
{
chart: {
smeup: {
fun: "F(EXA;SERV;MET)",
options: {
Typ: ChartType.LINE,
Series: "VALORI|VALCAL",
Title: "Monthly Values Chart",
ForceWidth: "500",
ForceHeight: "300",
} as ChartOptions,
},
},
margin: [0, 0, 0, 20],
},
// Bar Chart
{
chart: {
smeup: {
fun: "F(EXA;SERV;MET)",
options: {
Typ: ChartType.BAR,
Series: "VALORI|VALCAL",
Title: "Monthly Values Chart",
ForceWidth: "500",
ForceHeight: "300",
} as ChartOptions,
},
},
margin: [0, 0, 0, 20],
},
// Pie Chart
{
chart: {
smeup: {
fun: "F(EXA;SERV;MET)",
options: {
Typ: ChartType.PIE,
Series: "VALORI",
Title: "Monthly Values Chart",
ForceWidth: "500",
ForceHeight: "300",
} as ChartOptions,
},
},
},
],
};
const context = {
webupManagerData,
getSmeupDataStructure: async (fun: string) => {
return await fetchChartData(fun);
},
};
const pdf = await pdfmakeDocumentToPdfData(doc, context);
await fs.writeFile("charts.pdf", pdf);Generates line, bar, and pie charts as SVG images embedded in PDF documents.
Box Layouts
import { BoxOptions } from "@sme.up/doc-alchemist";
const doc = {
content: [
// Single Column Layout
{ text: "Single column with default layout", fontSize: 14, bold: true },
{
box: {
smeup: {
fun: "F(EXB;SERV;MET)",
options: {
Columns: "col1|col2|col3|col4|col5",
Cols: "1",
} as BoxOptions,
},
},
margin: [0, 0, 0, 20],
},
// Three Column Layout
{ text: "Three columns layout", fontSize: 14, bold: true },
{
box: {
smeup: {
fun: "F(EXB;SERV;MET)",
options: {
Columns: "col1|col4|col5",
Cols: "3",
LayoutNbr: "2",
} as BoxOptions,
},
},
margin: [0, 0, 0, 20],
},
// Two Column Layout with Images
{ text: "Two columns with images", fontSize: 14, bold: true },
{
box: {
smeup: {
fun: "F(EXB;SERV;MET)",
options: {
Columns: "img|col1|col4|col5",
Cols: "2",
LayoutNbr: "5",
} as BoxOptions,
},
},
},
],
styles: {
box__label: { fontSize: 10, color: "#990000" },
box__value: { fontSize: 10, bold: true },
},
};
const pdf = await pdfmakeDocumentToPdfData(doc, context);
await fs.writeFile("box-layout.pdf", pdf);Creates flexible box layouts with 1, 2, or 3 columns, supporting different layout patterns and image integration.
Cell Styling in Tables
const dataTable = {
type: SmeupDataStructureType.SmeupDataTable,
columns: [
{ name: "col1", title: "Product" },
{ name: "col2", title: "Status" },
],
rows: [
{
cells: {
col1: {
value: "Item 1",
styleAttributes: {
FontULine: "Yes",
FontBold: "Yes",
FontItalic: "Yes",
FontColor: "R000G000B150",
BackColor: "R173G219B239",
},
},
col2: { value: "Active" },
},
},
],
};
const doc = {
content: [
{
table: {
smeup: { data: dataTable },
},
},
],
};
const pdf = await pdfmakeDocumentToPdfData(doc, { webupManagerData });
await fs.writeFile("styled-table.pdf", pdf);Applies custom styling to individual cells including colors, bold, italic, and underline.
Excel Export
Export SmeUP DataTable to Excel
import { dataTableToExcelData } from "@sme.up/doc-alchemist";
const dataTable = {
type: SmeupDataStructureType.SmeupDataTable,
columns: [
{ name: "col1", title: "Name" },
{ name: "col2", title: "Value" },
],
rows: [
{ cells: { col1: { value: "Item 1" }, col2: { value: "100" } } },
{ cells: { col1: { value: "Item 2" }, col2: { value: "200" } } },
],
};
const excelBuffer = await dataTableToExcelData(
dataTable,
webupManagerData,
"Sheet1",
);
await fs.writeFile("output.xlsx", excelBuffer);Export SmeUP DataTree to Excel
import { dataTreeToExcelData } from "@sme.up/doc-alchemist";
const dataTree = {
type: SmeupDataStructureType.SmeupDataTree,
columns: [
{ name: "col1", title: "Category" },
{ name: "col2", title: "Count" },
],
children: [
{
value: "Parent 1",
cells: { col1: { value: "Parent 1" }, col2: { value: "10" } },
children: [
{
value: "Child 1.1",
cells: { col1: { value: "Child 1.1" }, col2: { value: "5" } },
children: [],
},
],
},
],
};
const excelBuffer = await dataTreeToExcelData(
dataTree,
webupManagerData,
"TreeSheet",
);
await fs.writeFile("tree.xlsx", excelBuffer);Exports hierarchical tree structures to Excel with proper indentation.
Chart Generation
Generate Chart as SVG
import { dataTableToChart } from "@sme.up/doc-alchemist";
import { ChartType } from "@sme.up/doc-alchemist";
const chartData = {
type: SmeupDataStructureType.SmeupDataTable,
columns: [
{ name: "month", title: "Month" },
{ name: "sales", title: "Sales" },
],
rows: [
{ cells: { month: { value: "Jan" }, sales: { value: "1000" } } },
{ cells: { month: { value: "Feb" }, sales: { value: "1500" } } },
{ cells: { month: { value: "Mar" }, sales: { value: "1200" } } },
],
};
const chartOptions = {
Typ: ChartType.BAR,
Series: "sales",
Title: "Monthly Sales",
ForceWidth: "600",
ForceHeight: "400",
};
const chartSvg = await dataTableToChart(chartData, chartOptions);
await fs.writeFile("chart.svg", chartSvg);Generates standalone chart SVG strings from SmeUP data structures using ECharts.
PDF Form Filling
Fill Existing PDF Forms
import { fillPdfForm } from "@sme.up/doc-alchemist";
const templatePdf = await fs.readFile("template.pdf");
const formData = {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phone: "555-1234",
};
const filledPdf = await fillPdfForm(templatePdf, formData, {
flatten: true, // Optional: flatten form fields after filling
});
await fs.writeFile("filled-form.pdf", filledPdf);Fills existing PDF forms with data and optionally flattens fields to prevent further editing.
Advanced Features
Mixed Content in Single Document
const doc = {
content: [
{
text: "Complete Report",
fontSize: 24,
bold: true,
margin: [0, 0, 0, 20],
},
// Section with table
{ text: "Data Summary", fontSize: 18, bold: true, margin: [0, 0, 0, 10] },
{
table: {
smeup: { fun: "F(EXB;SERV;MET)" },
},
layout: "lightHorizontalLines",
margin: [0, 0, 0, 20],
},
// Section with chart
{
text: "Visual Analysis",
fontSize: 18,
bold: true,
margin: [0, 0, 0, 10],
},
{
chart: {
smeup: {
fun: "F(EXA;SERV;MET)",
options: {
Typ: ChartType.LINE,
Series: "VALORI|VALCAL",
Title: "Trend Analysis",
ForceWidth: "500",
ForceHeight: "300",
},
},
},
margin: [0, 0, 0, 20],
},
// Section with images
{
text: "Supporting Images",
fontSize: 18,
bold: true,
margin: [0, 0, 0, 10],
},
{
columns: [
{
image: {
smeup: { url: "https://example.com/image1.png" },
},
width: 200,
},
{
image: {
smeup: { obj: { t: "CN", p: "COL", k: "LOGO" } },
},
width: 200,
},
],
},
],
header: {
text: "Page [CurrentPage] of [PageCount]",
alignment: "right",
margin: [40, 20],
},
};
const pdf = await pdfmakeDocumentToPdfData(doc, context);
await fs.writeFile("complete-report.pdf", pdf);Combines tables, charts, images, and formatted text in a single comprehensive document.
API Reference
Core Functions
dataTableToPdfData(component, webupManagerData)
Generates a simple PDF from a SmeUP DataTable with automatic formatting and cover page.
const pdf = await dataTableToPdfData(
component: {
smeupDataTable: SmeupDataTable,
props: GenericObject
},
webupManagerData: WebupManagerData
): Promise<Buffer | Uint8Array>Best for quick table exports with minimal configuration. Includes automatic cover page generation with titles and logos.
pdfmakeDocumentToPdfData(doc, context)
Converts a pdfmake document definition into PDF binary data.
const pdf = await pdfmakeDocumentToPdfData(
doc: TDocumentDefinitions,
context: Partial<PdfMakeConverterContext>
): Promise<Uint8Array>dataTableToExcelData(dataTable, webupManagerData, sheetName)
Exports SmeUP DataTable to Excel format.
const excel = await dataTableToExcelData(
dataTable: SmeupDataTable,
webupManagerData: WebupManagerData,
sheetName?: string
): Promise<Buffer>dataTreeToExcelData(dataTree, webupManagerData, sheetName)
Exports SmeUP DataTree to Excel format with hierarchy.
const excel = await dataTreeToExcelData(
dataTree: SmeupDataTree,
webupManagerData: WebupManagerData,
sheetName?: string
): Promise<Buffer>dataTableToChart(dataTable, options)
Generates chart SVG string from SmeUP data.
const svg = await dataTableToChart(
dataTable: SmeupDataTable,
options: ChartOptions
): Promise<string>fillPdfForm(pdfBuffer, formData, options)
Fills existing PDF forms with data.
const filled = await fillPdfForm(
pdfBuffer: Uint8Array,
formData: Record<string, string>,
options?: FillPdfFormOptions
): Promise<Uint8Array>Context Configuration
interface PdfMakeConverterContext {
webupManagerData: WebupManagerData;
getSmeupDataStructure?: (fun: string) => Promise<any>;
fetchData?: (url: string) => Promise<Response>;
damSvcEndpoint?: string;
}
interface WebupManagerData {
mathLocale: string;
datesLocale: string;
themeBackground: string;
}Development
Build
npm run buildTest
npm testDebug Examples
Run the debug script to see all features in action:
npm startThis generates sample PDFs in the output/ directory demonstrating all capabilities.
License
Apache-2.0
Support
For issues and feature requests, visit: GitHub Repository
Additional Resources
- See debug-pdfmake.ts for complete working examples
- Check the
tests/directory for unit test examples - Explore the
src/types/directory for TypeScript type definitions
