Rendering Print Preview from any Dialog
When trying to print a PDF document from a popup dialog (e.g., a modal), the print layout can sometimes be blocked or appeared incorrectly because:
- CSS Interference: The styles applied to the dialog (e.g.,
position: fixed
,z-index
,background
, etc.) can interfere with the print layout. - Browser Behavior: Browsers may not handle printing of
position: fixed
orabsolute
elements correctly. - Hidden Content: Content outside the dialog (e.g., the rest of the page) might still be included in the print output.
To display print preview correctly, you need to ensure that only the content of the Vue PDF Viewer on the dialog is printed and that it is styled correctly for printing. You can achieve this by using CSS to hide unnecessary elements and adjust the layout for printing.
Key points
Use
@media print
to control print styles:- Apply the
@media print
CSS rule to define styles specifically for printing. - Find the nearest ancestor selector of the Vue PDF Viewer container to style it correctly for printing.
- Apply the
Hide the Dialog Mask:
- The dialog mask (often a
position: fixed
orabsolute
overlay) should be hidden during printing to prevent it from interfering with the layout. Usedisplay: none !important;
for the mask.
- The dialog mask (often a
Ensure Content Visibility:
- Make the nearest ancestor of the content container visible by setting its visibility to visible and adjusting its layout for printing (e.g., removing position: fixed or absolute and ensuring it's not clipped).
Example with PrimeVue Dialog
<script setup>
import { ref } from 'vue';
import Dialog from 'primevue/dialog';
import VPdfViewer from '@vue-pdf-viewer/viewer';
const visible = ref(false);
</script>
<template>
<div>
<button @click="visible = true">Open Dialog</button>
<Dialog
v-model:visible="visible"
modal
header="Preview PDF"
class="my-dialog"
:style="{ width: '55rem', height: '55rem' }"
>
<template #header>
<p :style="{ textAlign: 'center' }">Preview PDF</p>
</template>
<VPdfViewer
src="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"
:style="{ width: '100%', height: '100%' }"
/>
<template #footer>
<button @click="visible = false">Close</button>
</template>
</Dialog>
</div>
</template>
<style>
@media print {
/* Hide the dialog mask */
.p-dialog-mask {
display: none !important;
}
/* Style the nearest ancestor of the Vue PDF Viewer container */
.p-dialog-content {
position: relative; /* Ensure it's not fixed or absolute */
display: block !important; /* Ensure it's visible */
overflow: visible; /* Ensure no content is clipped */
}
}
</style>
Example with Quasar Dialog
<script setup>
import { ref } from 'vue';
import VPdfViewer from '@vue-pdf-viewer/viewer';
const visible = ref(false);
</script>
<template>
<div>
<button @click="visible = true">Open Dialog</button>
<QDialog v-model:visible="visible">
<div style="height: 600px;">
<VPdfViewer
src="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"
/>
</div>
</QDialog>
</div>
</template>
<style>
@media print {
.q-dialog .q-dialog__backdrop {
display: none !important;
}
.q-dialog .q-dialog__inner {
position: relative !important;
display: block !important;
}
}
</style>
Workaround: Download and Print via Browser
If the printing issue still persists, alternatively, you could implement a workaround by downloading and opening a PDF file in a new tab via the browser's native print function.
Here's an example of how to download and open the PDF file in a new tab to print it:
<script setup>
import { ref, computed } from 'vue';
import VPdfViewer from '@vue-pdf-viewer/viewer';
const pdfUrl = ref('https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf');
const downloadAndOpenInNewTab = async () => {
const pdfData = await fetch(pdfUrl.value).then((res) =>
res.blob()
);
// Ensure the PDF file is not downloaded and opened in a new tab.
const pdfBlob = new Blob([pdfData], { type: 'application/pdf' });
const blobUrl = URL.createObjectURL(pdfBlob);
window.open(blobUrl, '_blank');
};
</script>
<template>
<div style="height: 600px;">
<VPdfViewer
:src="pdfUrl"
/>
</div>
</template>
⚠️ Although this method avoids potential styling issues, the PDF file is from the original src and not from a live input. This means if you fill up a PDF form in Vue PDF Viewer, the printed PDF will not contain updated content.
Remark: As implementing the workaround is not ideal, please reach out to us if you are facing this issue.