LogoLogo
Join our community
  • AdminJS
  • Contribute
  • Demo
  • Addons Marketplace
  • Installation
    • Getting started
    • Plugins
      • Adonis
      • Express
      • Nest
      • Fastify
      • Hapi
      • Koa
      • Community Plugins
        • FeathersJS
        • AdonisJS
      • Matrix
    • Adapters
      • TypeORM
      • Sequelize
      • Prisma
      • MikroORM
      • Objection
      • SQL
      • Mongoose
      • Community Adapters
        • AdonisJS
    • What's new in v7?
    • Migration Guide v7
  • Basics
    • Resource
    • Action
    • Property
    • Features
      • Relations
      • Upload
      • Logger
      • Import & Export
      • Password
      • Leaflet Maps
      • Writing your own features
    • API
      • List
      • New
      • Search
      • Show
      • Edit
      • Delete
      • Bulk Delete
    • Themes
    • Authentication
      • FirebaseAuthProvider
      • MatrixAuthProvider
  • How to write an addon?
  • UI Customization
    • Writing your own Components
    • Overwriting CSS styles
    • Dashboard customization
    • Changing the form view
    • Storybook
  • Tutorials
    • Role-Based Access Control
    • Internationalization (i18n)
    • Content Management System
    • Custom components library
    • Custom component internationalization
  • FAQ
    • PDF Generator
    • Charts
    • Forgot Password
  • ⚠️Legacy documentation
Powered by GitBook
On this page
  1. FAQ

PDF Generator

For physical applications of AdminJS a pdf generator can come in handy, either for generating shipping labels or work orders.

PreviousCustom component internationalizationNextCharts

Last updated 2 years ago

In order to provide PDF generating capabilities within your AdminJS instance you will have to take advantage of the custom components feature and the .

First, create a new instance of the Component Loader, and create a Components object that will hold the custom components.

index.ts
const componentLoader = new ComponentLoader()

const Components = {
    PDFGenerator: componentLoader.add('GeneratePDF', './pdfgenerator.component')
}

Remember to !

Then, we will have to append the PDF generator to a resource and add a handler for the record passed within context.

order.resource.ts
const orderResource = {
    resource: Order,
    options: {
        actions: {
            PDFGenerator: {
                actionType: 'record',
                icon: 'GeneratePdf',
                component: Components.PDFGenerator,
                handler: (request, response, context) => {
                    const { record, currentAdmin } = context
                    return {
                        record: record.toJSON(currentAdmin),
                        url: pdfgenerator(record.toJSON(currentAdmin))
                    }
                }
            }
        }
    }
}

With that ready, we can focus on the PDF generator function.

pdfgenerator.ts
import { RecordJSON } from 'adminjs'
import { jsPDF } from 'jspdf'

const pdfGenerator = (record: RecordJSON): string => {
  const { params } = record
  const doc = new jsPDF()
  
  doc.text(params.orderNum, 10, 10) // example database column called orderNum
  doc.text(params.shippingAddress, 150, 10) // example database column called shippingAddress
  
  const filename = `/${params.id}.pdf`
  doc.save(`./pdfs${filename}`)
  
  return filename
}

export default pdfGenerator

Now that our PDFs can be created from the record passed within context, we will need to create a place where the pdfs will be stored. Create a folder called 'pdfs', which we will make public through express.

.
├── index.ts
├── order.resource.ts
├── pdfHandler.ts
├── pdfgenerator.component.tsx
├── pdfgenerator.ts
└── pdfs
    └── ...

Make sure you set the static path before building the router!

index.ts
import path from 'path'
import * as url from 'url'
// other imports

const __dirname = url.fileURLToPath(new URL('.', import.meta.url))

// ...

app.use(express.static(path.join(__dirname, 'pdfs/')))

Last, but not least, we need a way to open the freshly generated PDF file. Since we've already defined the custom component we're going to stick to the same naming scheme.

pdfgenerator.component.tsx
import React, { useEffect } from 'react'
import { ApiClient, ActionProps } from 'adminjs'
import { Loader } from '@adminjs/design-system'

const GeneratePdf: React.FC<ActionProps> = (props) => {
  const { record, resource } = props
  const api = new ApiClient()

  useEffect(() => {
    api.recordAction({
      recordId: record.id,
      resourceId: resource.id,
      actionName: 'PDFGenerator'
    }).then((response) => {
      window.location.href = response.data.url
    }).catch((err) => {
      console.error(err)
    })
  }, [])

  return <Loader />
}

export default GeneratePdf

jsPDF library
pass the Component Loader instance into your AdminJS config