Export resume as PDF
Add an export as PDF functionality to the resume builder. Integrate the jsPdf library into your app.
This lesson preview is part of the Interactive Vue.js Resume Builder course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Interactive Vue.js Resume Builder, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

[00:00 - 00:09] One of the most important parts of our application is to be able to save the resume as a PDF. After all, we want users to be able to apply with this resume.
[00:10 - 00:15] The user can send this resume digitally via email, LinkedIn, etc. Or even print it out.
[00:16 - 00:31] One option would be to let the user print the resume directly from the app with the browser's window print API. The problem is that this will often distort the look of the resume. For example, by adding a default header and footer, decreasing the quality, etc .
[00:32 - 00:43] Every browser has a different default setting, so it is hard to provide this functionality in a good way for our users. The better option is to export the resume with the PDF library.
[00:44 - 00:53] We want to add an export as PDF button. Since we will use more buttons and future lessons, we will create a custom button component first.
[00:54 - 01:09] This way, we can add a scope button style to this component, and all the custom components will look similar. We create custom button.view file in the components directory.
[01:10 - 01:35] In the template section, we add button tags. Inside this button, we add a slot.
[01:36 - 01:49] This way, the content of the button can be passed in from the parent component. All the buttons will get the class button and another dynamic class for the button type.
[01:50 - 02:13] As a value, we pass in the name of the computed property. In order to generate the custom class, we will receive the prop button type.
[02:14 - 02:46] We set an empty string as a default value to make this prop optional. The prop value will be primary or secondary, for example, and we want to generate classes such as button primary and button secondary based on that.
[02:47 - 03:19] For that, we add a computed property where we concatenate the string button with the prop value. For those classes, we add some styling as well in the scoped styling section.
[03:20 - 03:32] All buttons will get default styling with the button class. For those classes, we add a similar color to the color.
[03:33 - 03:53] For those classes, we add a similar color to the color. For those classes, we add a similar color to the color.
[03:54 - 04:19] But the buttons that also get a custom class, such as button primary, will overwrite the default styling. For those classes, we add a similar color to the color.
[04:20 - 04:53] For those classes, we add a similar color to the color. For those classes, we add a similar color to the color.
[04:54 - 05:09] Now that we have a standardized button component, we will create an export PDF component. In the export PDF component, we will use the custom button component.
[05:10 - 06:17] As we did before, many times in the app component, we first import the component, register it in the components object, and then we can use it in the template. We add the text export resume as PDF to be rendered inside the slot, so as the button text.
[06:18 - 06:38] And add the prop button type primary. The button gets an event listener that listens to the click event and calls an event handler that we call export PDF.
[06:39 - 07:17] Before we add the implementation of the export PDF method that fires when the button is clicked, one thing I want to do is to see the component displayed. For that, we need to import the export PDF in the app component and register it .
[07:18 - 07:55] For now, we will just add it somewhere in the sidebar. Before triggering the export, we need to make sure that the editing mode is off visualizations.
[07:56 - 08:18] . One way to achieve this is by adding a vif directive to the components text. Now, this component is only shown if editing is false because we can negate the value, so only then it would evaluate to true.
[08:19 - 08:27] And, but therefore show. So the user can only use the export PDF button when editing mode is toggled off .
[08:28 - 08:50] While we are added, we will add vif editing to the elements in the sidebar that should only be visible when editing is on. This way, all those configuration options will be removed when editing mode is off, and the user can focus on the export options.
[08:51 - 09:27] To clarify to the user that they have to toggle the switch to see the export options, we want to display edit mode on one side of the switch and export mode on the other. To accomplish this, we add the prop off-label to the target switch component.
[09:28 - 09:53] In the component, we register the prop and display it on the left side of the switch. Since we are using the target switch component also for the image toggle, we make this prop optional and only displays value if it is passed down.
[09:54 - 10:31] And pass export mode as its value to the target switch component. [silence] Now that we have taken care of displaying the PDF export button, we will turn our attention to adding the functionality.
[10:32 - 10:50] To facilitate the conversion of the resume into PDF, we will be using the HTML to PDF.js library, which is a popular library for exporting PDFs on the client side. We will add the library with the CDN link.
[10:51 - 11:05] There are different versions, but we will be using version 0.9.3 of the library . I will just add the CDN link underneath our main.js script in the index.html file.
[11:06 - 11:21] You can just copy the link from the video script. The library has many configuration options that are all well documented.
[11:22 - 11:35] First, we want to see what we get with the default export without any extra configuration. We just select the resume node by its ID and call the libraries method.
[11:36 - 12:12] We call the libraries method by chaining them as shown in the documentation. [silence] Let's try it out by using the button that we created.
[12:13 - 12:47] [silence] The reason our resume is so far moved to the right when we try to print it out, or when we try to export it, is because we have margin left set on the resume. We have to move that to another element in order to keep the positioning of the resume in the page, but also not the storage resume when exporting it.
[12:48 - 13:10] For that, I will add a wrapper around the resume. [silence] Let's move the respective styling over to this wrapper.
[13:11 - 13:39] [silence] When we inspect it in the browser, we see that the positioning of the resume hasn't changed, and now let's try out the exporting. [silence] This looks good.
[13:40 - 13:59] [silence] Seems like the default settings for the HTML2 PDF library are just what we want . [silence] Let's take a look at the documentation to see which options we have in case we would want to adjust something.
[14:00 - 14:19] [silence] We can pass on a configuration object by calling the set method and passing in an object. The set method has to be called before the from method.
[14:20 - 14:30] The margin is zero by default, but I still want to add it in order to make the setting more explicit. We can also add a file name property to the configuration object.
[14:31 - 14:43] We will call the exported PDF, resume per default. The browser will prompt the user to confirm saving the file anyway, so the user has a chance to adjust the file name before saving it.
[14:44 - 15:20] [silence] Another option we want to make explicit is the JS PDF property. This property's value is an object with several optional properties.
[15:21 - 15:36] We want the orientation to be portrait, the unit, mm for millimeter, and the format to be a4. These are the specifications needed for an a4 format.
[15:37 - 15:53] There are more options we can use to customize with the JS PDF property. You can view all of them in this documentation.
[15:54 - 16:13] [silence] Let's try out this configuration. [silence] As you can see, we get the same result.
[16:14 - 16:29] I mentioned earlier in this course how both a4 as well as us letter formats are used depending on your geographic location. We want to give the user the option to choose this and then adjust the format and unit properties accordingly.
[16:30 - 16:41] We can provide the user with this option very easily. First, we add resume format to the data object of the app component and set the default value to a4.
[16:42 - 17:05] [silence] The user will get two options to choose from, a4 and letter. For this, we can use the select input component.
[17:06 - 17:21] [silence] For the label, we pass resume format. For options, we use the name a4 and letter.
[17:22 - 17:52] [silence] For the default option prop, we pass on the data property that we just created. [silence] For the inline event handler, we can use the data property.
[17:53 - 18:02] Resume format and set it equal to the event. You can refer to how we used this component before, if you are unsure.
[18:03 - 18:25] There are two things we want to react to this value, the width and the height of the resume in the CSS and the format and unit values and the export PDF method. [silence] For the styling, we have previously given the resume the default height and width for the a4 format.
[18:26 - 18:39] This can remain as the default styling since a4 is the default format. If resume format is set to letter, we will add the class letter format to the dynamic class attribute.
[18:40 - 19:06] [silence] In the styling, we can then overwrite the height and the width for the case where the class letter format is added. [silence] Try out switching between these two options and the select element.
[19:07 - 19:20] You can see that the letter format is a bit wider but therefore shorter than in the h4 format. [silence] In our export PDF method, we want to adjust unit and format.
[19:21 - 19:58] In order to notify our export PDF component about the current format, we pass it in as a prop. [silence] For the unit, we use millimeters or so mm or in 4-inch.
[19:59 - 20:18] Depending on the chosen format. [silence] We use the ternary operator instead of the FS statement here.
[20:19 - 20:51] With this expression, millimeter gets assigned to the unit variable, fa4 selected, and otherwise, inch gets assigned. [silence] Try out exporting the resume with these two formats.
[20:52 - 22:18] [silence] [music] [music] [music] [music] [music]