DEV Community

sunshey
sunshey

Posted on

How to Convert Excel to PDF in the Browser with Vue 3

Converting Excel spreadsheets to PDF involves parsing tabular data, handling multiple sheets, and rendering it all cleanly to a PDF document.

Here's how to build a browser-based Excel to PDF converter with Vue 3.

The challenge: Tables to PDF

Excel to PDF conversion involves:

  1. Parsing Excel structure (sheets, rows, columns, merged cells)
  2. Determining page layout and pagination
  3. Rendering tables with proper alignment
  4. Handling different file formats (XLSX, XLS, CSV, ODS)

The stack

  • Vue 3 with Composition API
  • SheetJS (xlsx) for Excel parsing
  • jsPDF for PDF generation
  • Vite for bundling

The core implementation

<script setup lang="ts">
import { ref } from 'vue'
import * as XLSX from 'xlsx'
import jsPDF from 'jspdf'

const file = ref<File | null>(null)
const workbook = ref<any>(null)
const sheets = ref<string[]>([])
const selectedSheet = ref<string>('')

async function handleFile(e: Event) {
  const input = e.target as HTMLInputElement
  if (!input.files?.[0]) return
  file.value = input.files[0]

  const buffer = await file.value.arrayBuffer()
  workbook.value = XLSX.read(buffer, { type: 'array' })
  sheets.value = workbook.value.SheetNames
  selectedSheet.value = sheets.value[0]
}

async function convertToPdf() {
  if (!workbook.value || !selectedSheet.value) return

  const sheetName = selectedSheet.value
  const worksheet = workbook.value.Sheets[sheetName]
  const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1')

  const pdf = new jsPDF({
    orientation: range.e.c > range.b.c ? 'landscape' : 'portrait',
    unit: 'mm',
    format: 'a4'
  })

  const marginLeft = 10
  let y = 10

  // Render each row
  for (let row = range.s.r; row <= range.e.r; row++) {
    for (let col = range.s.c; col <= range.e.c; col++) {
      const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]
      if (!cell) continue

      const x = marginLeft + col * 30
      const text = String(cell.v ?? '')

      pdf.text(text, x, y)
    }
    y += 7
  }

  pdf.save(`${sheetName}.pdf`)
}
</script>
Enter fullscreen mode Exit fullscreen mode

Key implementation details

1. Excel parsing with SheetJS

SheetJS reads all Excel formats into a unified structure:

const workbook = XLSX.read(buffer, { type: 'array' })
const sheets = workbook.SheetNames
Enter fullscreen mode Exit fullscreen mode

2. Range detection

Calculate the data range to know what to render:

const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1')
Enter fullscreen mode Exit fullscreen mode

3. Page orientation

Detect wide tables and switch to landscape:

const isWide = range.e.c > range.b.c * 1.5
const orientation = isWide ? 'landscape' : 'portrait'
Enter fullscreen mode Exit fullscreen mode

4. Cell rendering

Draw each cell as text with proper spacing:

pdf.text(String(cell.v ?? ''), x, y)
Enter fullscreen mode Exit fullscreen mode

Limitations

Complex formatting

Cell colors, fonts, and borders are not preserved in the basic implementation.

Solution: Add cell style detection and apply matching PDF styles.

Merged cells

SheetJS exposes merged cell ranges but jsPDF doesn't support cell merging natively.

Solution: Skip drawing text in merged cells and adjust column widths manually.

Large spreadsheets

Very large sheets can exceed PDF page limits or browser memory.

Solution: Add pagination logic and process sheets in chunks.

Formula cells

Formulas may not evaluate before rendering.

Solution: Force recalculation or pre-process with SheetJS utilities.

Summary

Building a browser-based Excel to PDF converter involves:

  1. Using SheetJS for parsing
  2. Detecting data ranges
  3. Rendering cells with jsPDF
  4. Handling pagination for large sheets

Try it at en.sotool.top/excel-to-pdf.

Top comments (0)