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:
- Parsing Excel structure (sheets, rows, columns, merged cells)
- Determining page layout and pagination
- Rendering tables with proper alignment
- 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>
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
2. Range detection
Calculate the data range to know what to render:
const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1')
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'
4. Cell rendering
Draw each cell as text with proper spacing:
pdf.text(String(cell.v ?? ''), x, y)
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:
- Using SheetJS for parsing
- Detecting data ranges
- Rendering cells with jsPDF
- Handling pagination for large sheets
Try it at en.sotool.top/excel-to-pdf.
Top comments (0)