Skip to content

🎯 Angular library for exporting HTML/Table elements to PDF, Excel, Word, CSV, JSON, XML, PNG and more. Standalone-first architecture with TypeScript support. Compatible with Angular 21+ and Ionic/Capacitor. Zero-config, lightweight, and fully customizable.

License

Notifications You must be signed in to change notification settings

wnabil/ngx-export-as

Repository files navigation

ngx-export-as

npm version License: MIT

Angular service for exporting HTML/Table elements to multiple file formats

A powerful and flexible Angular library that enables exporting HTML content, tables, and DOM elements to various file formats including PDF, Excel, Word, images, and more. Built with TypeScript and fully compatible with Angular 21+ and Ionic/Capacitor.


πŸ“‹ Table of Contents


✨ Features

  • 🎯 Multiple Export Formats - Support for 10+ file formats
  • πŸ“¦ Zero Configuration - Works out of the box with sensible defaults
  • 🎨 Customizable - Extensive options for each export format
  • πŸš€ Lightweight - Minimal dependencies and optimized bundle size
  • πŸ”§ TypeScript - Full type safety and IntelliSense support
  • ⚑ Standalone-First - Modern Angular architecture (v1.21.0+)
  • 🌐 SSR Compatible - Server-side rendering support with platform checks
  • πŸ“± Ionic/Capacitor Ready - Works seamlessly with Ionic/Capacitor applications
  • πŸŽͺ Two Export Modes - Download files or retrieve base64 content
  • β™Ώ IE Support - Compatible with Internet Explorer (with polyfills)

πŸ“„ Supported Formats

Format Extension Description Table Required
PDF .pdf Portable Document Format ❌ No
PNG .png Image export ❌ No
Excel .xlsx, .xls Microsoft Excel spreadsheet βœ… Yes
Word .docx, .doc Microsoft Word document* ❌ No
CSV .csv Comma-separated values βœ… Yes
Text .txt Plain text file βœ… Yes
JSON .json JavaScript Object Notation βœ… Yes
XML .xml Extensible Markup Language βœ… Yes

Note: Word document export (.doc, .docx) requires TypeScript target configuration es2015 or higher. See this issue for details.


πŸ“¦ Installation

Using npm

npm install --save ngx-export-as

Using yarn

yarn add ngx-export-as

Using pnpm

pnpm add ngx-export-as

πŸš€ Quick Start

⚠️ Breaking Change in v1.21.0: ExportAsModule has been removed. The library now uses standalone components. See migration examples below.

Option 1: Standalone Component (Recommended)

Provide ExportAsService directly in your standalone component using modern inject():

import { Component, inject } from '@angular/core';
import { ExportAsService, ExportAsConfig } from 'ngx-export-as';

@Component({
  selector: 'app-export',
  templateUrl: './export.component.html',
  standalone: true,
  providers: [ExportAsService]  // Provide service in component
})
export class ExportComponent {
  private readonly exportAsService = inject(ExportAsService);
  
  // Your export methods here
}

Option 2: App-Wide Provider (app.config.ts)

For using the service across multiple components, provide it globally in app.config.ts:

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { ExportAsService } from 'ngx-export-as';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    ExportAsService  // Available throughout the app
  ]
};

Then use it in any component:

import { Component, inject } from '@angular/core';
import { ExportAsService, ExportAsConfig } from 'ngx-export-as';

@Component({
  selector: 'app-export',
  templateUrl: './export.component.html',
  standalone: true
  // No need to provide service here - already in app.config
})
export class ExportComponent {
  private readonly exportAsService = inject(ExportAsService);
}

Option 3: Legacy NgModule (For Older Projects)

If you're still using NgModule-based architecture:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ExportAsService } from 'ngx-export-as';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [ExportAsService],  // Add service to providers
  bootstrap: [AppComponent]
})
export class AppModule { }

Then inject in your component:

import { Component, inject } from '@angular/core';
import { ExportAsService, ExportAsConfig } from 'ngx-export-as';

@Component({
  selector: 'app-export',
  templateUrl: './export.component.html'
})
export class ExportComponent {
  private readonly exportAsService = inject(ExportAsService);
}

2. Add HTML Element and Export Method

Create an HTML element with an ID to export:

<div id="contentToExport">
  <h1>My Report</h1>
  <table>
    <tr>
      <th>Name</th>
      <th>Age</th>
      <th>City</th>
    </tr>
    <tr>
      <td>John Doe</td>
      <td>30</td>
      <td>New York</td>
    </tr>
  </table>
</div>

<button (click)="exportAsPDF()">Export as PDF</button>

Implement the export method:

exportAsPDF() {
  const exportConfig: ExportAsConfig = {
    type: 'pdf',
    elementIdOrContent: 'contentToExport'
  };
  
  this.exportAsService.save(exportConfig, 'MyReport').subscribe(() => {
    console.log('PDF export started');
  });
}

πŸ’‘ Usage Examples

Download File (Automatic)

Export and automatically download the file:

import { Component, inject } from '@angular/core';
import { ExportAsService, ExportAsConfig } from 'ngx-export-as';

@Component({
  selector: 'app-export',
  standalone: true,
  providers: [ExportAsService]
})
export class ExportComponent {
  private readonly exportAsService = inject(ExportAsService);
  
  exportToPDF() {
    const config: ExportAsConfig = {
      type: 'pdf',
      elementIdOrContent: 'myTableId'
    };
    
    this.exportAsService.save(config, 'my-report').subscribe(() => {
      // File download started
      console.log('Export completed!');
    });
  }
}

Get Base64 Content

Retrieve the exported content as base64 for further processing:

getBase64Content() {
  const config: ExportAsConfig = {
    type: 'png',
    elementIdOrContent: 'chartElement'
  };
  
  this.exportAsService.get(config).subscribe((content: string) => {
    // Use base64 content for upload, preview, etc.
    console.log('Base64 content:', content);
    
    // Example: Upload to server
    this.uploadToServer(content);
    
    // Example: Display in image tag
    this.imagePreview = content;
  });
}

Export to Excel

Export table data to Excel spreadsheet:

exportToExcel() {
  const config: ExportAsConfig = {
    type: 'xlsx',
    elementIdOrContent: 'dataTable',
    options: {
      bookType: 'xlsx',
      sheet: 'Sheet1'
    }
  };
  
  this.exportAsService.save(config, 'data-export').subscribe(() => {
    console.log('Excel file downloaded');
  });
}

Export to JSON

Convert table data to JSON format:

exportToJSON() {
  const config: ExportAsConfig = {
    type: 'json',
    elementIdOrContent: 'userTable'
  };
  
  // Note: JSON returns actual objects, not base64
  this.exportAsService.get(config).subscribe((data: any[]) => {
    console.log('JSON data:', data);
    // Process JSON data
    this.processData(data);
  });
}

Multiple Export Buttons

<div id="reportContent">
  <!-- Your content here -->
</div>

<div class="export-buttons">
  <button (click)="export('pdf')">Export PDF</button>
  <button (click)="export('xlsx')">Export Excel</button>
  <button (click)="export('csv')">Export CSV</button>
  <button (click)="export('png')">Export Image</button>
</div>
export(format: 'pdf' | 'xlsx' | 'csv' | 'png') {
  const config: ExportAsConfig = {
    type: format,
    elementIdOrContent: 'reportContent'
  };
  
  this.exportAsService.save(config, `report-${Date.now()}`).subscribe(() => {
    console.log(`${format.toUpperCase()} export completed`);
  });
}

βš™οΈ Configuration

ExportAsConfig Interface

interface ExportAsConfig {
  type: SupportedExtensions;      // Required: Export format
  elementIdOrContent: string;     // Required: Element ID or content
  download?: boolean;             // Optional: Auto-download (used internally)
  fileName?: string;              // Optional: File name (used internally)
  options?: any;                  // Optional: Format-specific options
}

Configuration Properties

Property Type Required Description
type SupportedExtensions βœ… Yes The export file format (pdf, png, xlsx, etc.)
elementIdOrContent string βœ… Yes The HTML element ID to export
download boolean ❌ No Internal flag for download mode
fileName string ❌ No Internal filename (set via save() method)
options any ❌ No Format-specific configuration options

πŸŽ›οΈ Format-Specific Options

PDF Options

Powered by html2pdf.js:

const config: ExportAsConfig = {
  type: 'pdf',
  elementIdOrContent: 'content',
  options: {
    margin: 10,
    filename: 'report.pdf',
    image: { type: 'jpeg', quality: 0.98 },
    html2canvas: { 
      scale: 2,
      useCORS: true,
      logging: false
    },
    jsPDF: { 
      unit: 'mm', 
      format: 'a4', 
      orientation: 'portrait' 
    },
    // Custom PDF manipulation
    pdfCallbackFn: (pdf) => {
      // Add page numbers
      const pageCount = pdf.internal.getNumberOfPages();
      for (let i = 1; i <= pageCount; i++) {
        pdf.setPage(i);
        pdf.setFontSize(10);
        pdf.text(`Page ${i} of ${pageCount}`, 
          pdf.internal.pageSize.getWidth() / 2, 
          pdf.internal.pageSize.getHeight() - 10,
          { align: 'center' }
        );
      }
    }
  }
};

Common PDF Options:

  • margin: Margin size (number or object with top, right, bottom, left)
  • filename: Output filename
  • image: Image export options (type, quality)
  • html2canvas: Canvas rendering options
  • jsPDF: PDF generation options (unit, format, orientation)
  • pdfCallbackFn: Custom callback function for PDF manipulation

PNG Options

Powered by html2canvas:

const config: ExportAsConfig = {
  type: 'png',
  elementIdOrContent: 'chart',
  options: {
    scale: 2,                    // Higher quality (2x resolution)
    backgroundColor: '#ffffff',  // Background color
    logging: false,              // Disable console logs
    useCORS: true,              // Enable cross-origin images
    allowTaint: false,          // Prevent canvas tainting
    width: 1920,                // Custom width
    height: 1080                // Custom height
  }
};

Excel Options

Powered by SheetJS (xlsx):

const config: ExportAsConfig = {
  type: 'xlsx',
  elementIdOrContent: 'dataTable',
  options: {
    bookType: 'xlsx',
    sheet: 'Sales Data',
    raw: false,                  // Parse formatted values
    dateNF: 'yyyy-mm-dd',       // Date format
    cellDates: true             // Keep dates as date objects
  }
};

Word Document Options

Powered by html-docx-js:

⚠️ Important: Requires TypeScript target: "es2015" or higher in tsconfig.json

const config: ExportAsConfig = {
  type: 'docx',
  elementIdOrContent: 'document',
  options: {
    orientation: 'landscape',    // or 'portrait'
    margins: {
      top: '20',
      right: '20',
      bottom: '20',
      left: '20'
    }
  }
};

CSV/TXT Options

No additional options required. CSV format automatically quotes values and handles special characters.

JSON Options

No additional options. Returns actual JSON objects (not base64):

this.exportAsService.get(config).subscribe((data: any[]) => {
  // data is an array of objects
  console.log(data); // [{ name: 'John', age: '30' }, ...]
});

XML Options

No additional options. Converts table to structured XML format.


🌐 Browser Support

Modern Browsers

  • βœ… Chrome (latest)
  • βœ… Firefox (latest)
  • βœ… Safari (latest)
  • βœ… Edge (latest)
  • βœ… Opera (latest)

Internet Explorer Support

For IE11 support, you need to enable polyfills:

1. Enable Angular Polyfills

Uncomment the required polyfills in src/polyfills.ts:

// Enable all BROWSER POLYFILLS for IE support
import 'core-js/es/symbol';
import 'core-js/es/object';
import 'core-js/es/function';
import 'core-js/es/parse-int';
import 'core-js/es/parse-float';
import 'core-js/es/number';
import 'core-js/es/math';
import 'core-js/es/string';
import 'core-js/es/date';
import 'core-js/es/array';
import 'core-js/es/regexp';
import 'core-js/es/map';
import 'core-js/es/weak-map';
import 'core-js/es/set';

2. Add TypedArray Polyfill

Create src/polyfills/typedarray.js:

// TypedArray polyfill for IE
if (!Int8Array.__proto__) {
  console.log('Applying TypedArray polyfill...');
  // Polyfill implementation
  // See: https://github.com/inexorabletash/polyfill/blob/master/typedarray.js
}

Import in polyfills.ts:

import './polyfills/typedarray.js';

πŸŽͺ Demo

Running the Demo Application

Clone and run the demo application:

git clone https://github.com/wnabil/ngx-export-as.git
cd ngx-export-as
npm install
ng build ngx-export-as
ng serve

Then navigate to http://localhost:4200 in your browser.


πŸ“š Dependencies

This library uses the following open-source projects:

Library Version Purpose Documentation
html2canvas ^1.4.1 PNG image export Docs
html2pdf.js ^0.12.1 PDF generation Docs
SheetJS CE (xlsx) 0.20.3 Excel export Docs
html-docx-js - Word document export Docs

πŸ’‘ Tip: Refer to the individual library documentation for advanced configuration options.


πŸ”„ Migration Guide (v1.20.x β†’ v1.21.0)

Breaking Changes

Version 1.21.0 removes the ExportAsModule in favor of Angular's modern standalone architecture.

What Changed

  • ❌ Removed: ExportAsModule (no longer exported from the library)
  • βœ… New: Direct service provision in components or app.config.ts

Migration Steps

Before (v1.20.x):

// app.module.ts
import { ExportAsModule } from 'ngx-export-as';

@NgModule({
  imports: [
    BrowserModule,
    ExportAsModule  // ❌ No longer available
  ]
})
export class AppModule { }

After (v1.21.0) - Option 1: Standalone Component

import { Component } from '@angular/core';
import { ExportAsService } from 'ngx-export-as';

@Component({
  selector: 'app-export',
  standalone: true,
  providers: [ExportAsService]  // βœ… Provide directly
})
export class ExportComponent {
  private readonly exportAsService = inject(ExportAsService);
}

After (v1.21.0) - Option 2: App Config

// app.config.ts
import { ExportAsService } from 'ngx-export-as';

export const appConfig: ApplicationConfig = {
  providers: [ExportAsService]  // βœ… App-wide provider
};

After (v1.21.0) - Option 3: NgModule (Legacy)

// app.module.ts
import { ExportAsService } from 'ngx-export-as';

@NgModule({
  imports: [BrowserModule],
  providers: [ExportAsService]  // βœ… Add to providers instead
})
export class AppModule { }

πŸ“ Important Notes

Format-Specific Requirements

  1. Table Required Formats

    • The following formats require a valid HTML <table> element:
      • Excel (.xlsx, .xls)
      • CSV (.csv)
      • Text (.txt)
      • JSON (.json)
      • XML (.xml)
  2. JSON Format Behavior

    • Unlike other formats, JSON get() method returns actual JSON objects, not base64-encoded strings
    • First table row is used as object keys (headers)
    • Great for processing data in-memory before exporting
  3. Word Document Requirements

    • DOCX/DOC export requires TypeScript compiler target es2015 or higher
    • Update tsconfig.json:
      {
        "compilerOptions": {
          "target": "es2015"
        }
      }
  4. PDF Element Types

    • PDF export accepts multiple input types:
      • Element ID (string): 'myElementId'
      • HTMLElement: document.getElementById('myElement')
      • Canvas: Direct canvas element
      • Image: Image element or data URL
  5. SSR (Server-Side Rendering)

    • The library includes platform checks for SSR compatibility
    • Canvas-based exports (PDF, PNG) only work in browser context
    • Use base64 retrieval for Ionic/Capacitor or SSR applications

🀝 Contributing

Contributions are welcome! Here's how you can help:

Reporting Issues

Found a bug or have a feature request?

  1. Check existing issues first
  2. Create a new issue with:
    • Clear description
    • Angular version
    • Browser information
    • Reproduction steps
    • Code examples

Pull Requests

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes
  4. Test thoroughly
  5. Commit with clear messages: git commit -m "feat: add new feature"
  6. Push to your fork: git push origin feature/my-feature
  7. Submit a pull request

Development Setup

# Clone the repository
git clone https://github.com/wnabil/ngx-export-as.git
cd ngx-export-as

# Install dependencies
npm install

# Build the library
ng build ngx-export-as

# Run the demo app
ng serve

# Run tests
npm test

# Build for production
npm run package

Contact

πŸ“§ If you don't receive a response within 2 days, please follow up on your issue.


πŸ“„ License

This project is licensed under the MIT License.

MIT License

Copyright (c) 2025 Wassem Nabil

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

See LICENSE file for details.


πŸ™ Acknowledgments

Special thanks to all contributors who have helped improve this library:

And to all users who reported issues and provided feedback!


πŸ”— Links


Made with ❀️ by Wassem Nabil

If this library helped you, please consider giving it a ⭐ on GitHub!

About

🎯 Angular library for exporting HTML/Table elements to PDF, Excel, Word, CSV, JSON, XML, PNG and more. Standalone-first architecture with TypeScript support. Compatible with Angular 21+ and Ionic/Capacitor. Zero-config, lightweight, and fully customizable.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 10