How To Create A PDF Editor PWA Using VueJS

In this article, we have created a PWA with functionality of editing PDF files. The PDF editor PWA can be further customized by adding additional features.

How To Create A PDF Editor PWA Using VueJS
Photo by dlxmedia.hu / Unsplash

This guide will show you how to create a PDF editor PWA using Vue.js.

First, you will need to install the Vue.js CLI. This will allow you to create a new Vue.js project. Here's How To Do That

Once you have the CLI installed, create a new project by running the following command:

vue create pdf-editor-pwa

This will create a new directory called pdf-editor-pwa. Enter into this directory and you will see the following files and directories:

├── [README.md](<http://readme.md/>)
├── babel.config.js
├── package-lock.json
├── package.json
├── public
│   ├── favicon.ico
│   └── index.html
└── src
├── App.vue
├── assets
│   └── logo.png
├── components
│   └── HelloWorld.vue
└── main.js

The public directory contains the HTML file that will be used as the entry point for your PWA. The src directory contains the Vue.js components and assets.

Next, you will need to install the following dependencies:

vue-pdf: This is a Vue.js component that renders PDF files.
pdfjs-dist: This is a PDF library that will be used by the vue-pdf component.
@babel/polyfill: This is a Babel polyfill that will be used by the pdfjs-dist library.
babel-loader: This is a webpack loader that will be used by the pdfjs-dist library.

Run the following command to install these dependencies:

npm install vue-pdf pdfjs-dist @babel/polyfill babel-loader --save

Now that you have the dependencies installed, you can start coding the PDF editor PWA.

Open src/main.js and add the following code:

import Vue from 'vue'
import App from './App.vue'
import VuePdf from 'vue-pdf'
import 'pdfjs-dist/build/pdf.worker.entry.js'

Vue.use(VuePdf)
new Vue({
render: h => h(App)
}).$mount('#app')

This code imports the Vue.js library, the App.vue component, the vue-pdf component, and the PDF.js library. It then tells Vue.js to use the vue-pdf component and renders the App.vue component.

Next, open src/App.vue and add the following code:

<template>
<div id="app">
<pdf :file="file" @update:content="onContentUpdate">
<div class="pdf-editor-toolbar">
<button @click="undo">Undo</button>
<button @click="redo">Redo</button>
</div>
<div class="pdf-editor-content" contenteditable="true" @input="onContentChange">
{{content}}
</div>
</pdf>
</div>
</template>

<script>
import pdfjs from 'pdfjs-dist'
export default {
name: 'app',
data () {
return {
file: '',
content: '',
history: [],
currentIndex: -1
}
},
methods: {
onContentUpdate (content) {
this.content = content
},
onContentChange () {
if (this.content !== this.history[this.currentIndex]) {
this.history.push(this.content)
this.currentIndex = this.history.length - 1
}
},
undo () {
if (this.currentIndex > 0) {
this.currentIndex--
this.content = this.history[this.currentIndex]
}
},
redo () {
if (this.currentIndex < this.history.length - 1) {
this.currentIndex++
this.content = this.history[this.currentIndex]
}
}
},
mounted () {
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.entry.js'
this.file = '<https://vuejs.org/images/logo.png>'
}
}
</script>

<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}

.pdf-editor-toolbar {
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
}

.pdf-editor-content {
border: 1px solid #ccc;
padding: 20px;
}
</style>

This code creates a PDF editor that uses the vue-pdf component. It includes a toolbar with undo and redo buttons. The content of the PDF file is editable using the contenteditable attribute. The code also includes a history feature that allows you to undo and redo changes.

To test the PDF editor, start a development server by running the following command:

npm run serve

This will start a development server on http://localhost:8080. Open this URL in your browser and you should see the PDF editor.

To build the PDF editor for production, run the following command:

npm run build

This will build the PDF editor for production and output the files to the dist directory.

To add an image to the PDF editor, you will need to install the following dependencies:

file-saver: This is a library that will be used to save the edited PDF file.
@babel/runtime: This is a Babel runtime that will be used by the file-saver library.

Run the following command to install these dependencies:

npm install file-saver @babel/runtime --save

Once these dependencies are installed, you can add the following code to src/App.vue:

<template>
<div id="app">
<pdf :file="file" @update:content="onContentUpdate">
<div class="pdf-editor-toolbar">
<button @click="undo">Undo</button>
<button @click="redo">Redo</button>
<button @click="addImage">Add Image</button>
</div>
<div class="pdf-editor-content" contenteditable="true" @input="onContentChange">
{{content}}
</div>
</pdf>
</div>
</template>

<script>
import pdfjs from 'pdfjs-dist'
import { saveAs } from 'file-saver'

export default {
name: 'app',
data () {
return {
file: '',
content: '',
history: [],
currentIndex: -1
}
},
methods: {
onContentUpdate (content) {
this.content = content
},
onContentChange () {
if (this.content !== this.history[this.currentIndex]) {
this.history.push(this.content)
this.currentIndex = this.history.length - 1
}
},
undo () {
if (this.currentIndex > 0) {
this.currentIndex--
this.content = this.history[this.currentIndex]
}
},
redo () {
if (this.currentIndex < this.history.length - 1) {
this.currentIndex++
this.content = this.history[this.currentIndex]
}
},
addImage () {
const input = document.createElement('input')
input.type = 'file'
input.onchange = () => {
    const reader = new FileReader()
    reader.readAsDataURL(input.files[0])
    reader.onload = () => {
      const img = document.createElement('img')
      img.src = reader.result

      document.execCommand('insertImage', false, img.src)
    }
  }

  input.click()
}

},
mounted () {
pdfjs.GlobalWorkerOptions.workerSrc = 'pdf.worker.entry.js'
this.file = '<https://vuejs.org/images/logo.png>'
}
}
</script>

<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}

.pdf-editor-toolbar {
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
}

.pdf-editor-content {
border: 1px solid #ccc;
padding: 20px;
}
</style>

This code adds an addImage button to the toolbar. When this button is clicked, a file input is created. The user can select an image from their computer and it will be added to the PDF editor.

To test the PDF editor with the addImage feature, start a development server by running the following command:

npm run serve

This will start a development server on http://localhost:8080. Open this URL in your browser and you should see the PDF editor with the addImage button.

To build the PDF editor for production, run the following command:

npm run build

This will build the PDF editor for production and output the files to the dist directory.

In this article, we have created a PWA with functionality of editing PDF files. The PDF editor PWA can be further customized by adding additional features. For example, you could add a print button that prints the PDF document. You could also add a download button that downloads the edited PDF document.