Vue.js PDFMake.js Example to Export PDF Document From HTML Template Using vue-pdfmake Library & TypeScript Full Project For Beginners

  • Post author:
  • Post category:Vue
  • Post comments:0 Comments

 

 

 

App.vue

 

 

<template>
  <div style="height: 100%; width: 100%" id="app">
    <div style="width: 50%;display: inline-block;height: 100%;">
      <textarea
        @input="changeHandler"
        style="width: 100%; height: 200px;"
        v-model="value"
      ></textarea>
      <pdf-make
        ref="pdfMake"
        style="width: 100%"
        :show="true"
        :info="{ title: '测试' }"
        @change="e => (src = e)"
      >
        hello world
        <div style="font-size: 50px">
          <a
            style="margin-top: 20px; margin: 10px;"
            href="https://www.baidu.com"
          >
            {{ value }}
          </a>
        </div>
        <span style="font-weight: 600;text-align: center;">span</span>
        <img
          width="100px"
          src="https://is4-ssl.mzstatic.com/image/thumb/Purple128/v4/0b/18/23/0b18235d-9a98-e913-12db-2705bb5278d4/AppIcon-0-1x_U007emarketing-0-85-220-10.png/246x0w.jpg"
        />
      </pdf-make>
    </div>
    <iframe
      v-if="src"
      :src="src"
      style="width: 50%;display: inline-block;height: 100%;"
      frameborder="0"
    ></iframe>
  </div>
</template>

<script>
import PdfMake from './components/PdfMake'
import ttf from 'url-loader!./assets/微软雅黑.ttf'
console.log(ttf)
export default {
  name: 'app',
  components: {
    PdfMake,
  },
  data() {
    return {
      src: '',
      value: '',
    }
  },
  methods: {
    changeHandler() {
      this.$refs.pdfMake.createPdf()
    },
  },
}
</script>
<style>
html,
body {
  margin: 0px auto;
  padding: 0px;
  height: 100%;
}
#app {
  margin-bottom: -16px;
  display: flex;
}
</style>

 

 

pdfmake.vue

 

 

<template>
  <div v-show="show" class="vue-pdfmake-container">
    <slot name="background" />
    <slot name="header" :currentPage="1" :pageCount="1" :pageSize="1" />
    <slot />

    <slot name="footer" :currentPage="1" :pageCount="1" />
  </div>
</template>

<script>
import debounce from 'debounce'
import { vnodes2content } from './lib/vnodeHelper.js'
import pdfMake from './lib/pdfmake.js'
import {
  DEBOUNCE_TIME,
  PAGE_SIZE,
  PAFE_ORIENTATION,
  DOC_DEFINITION,
} from './lib/config.js'
export default {
  props: {
    show: {
      type: Boolean,
      default: true,
    },
    pageSize: {
      type: String,
      default: 'A4',
      validator(value) {
        return PAGE_SIZE.includes(value)
      },
    },
    pageOrientation: {
      type: String,
      default: 'portrait',
      validator(value) {
        return PAFE_ORIENTATION.includes(value)
      },
    },
    pageMargins: {
      type: Array,
    },
    info: {
      type: Object,
      default() {
        return {}
      },
    },
  },
  data() {
    return {
      background: [],
      content: [],
    }
  },
  computed: {
    docDefinition() {
      return {
        info: this.info,
        pageSize: this.pageSize,
        pageOrientation: this.pageOrientation,
        pageMargins: this.pageMargins,
        background: this.background,
        header: this.header,
        content: this.content,
        footer: this.footer,
        ...DOC_DEFINITION,
      }
    },
  },
  methods: {
    createPdf: debounce(function() {
      this.content = vnodes2content(this.$slots.default || []) // 正文
    }, DEBOUNCE_TIME),
  },
  watch: {
    docDefinition: {
      immediate: true,
      handler: debounce(function(docDefinition) {
        const pdfDocGenerator = pdfMake.createPdf(docDefinition)
        pdfDocGenerator.getDataUrl(dataUrl => {
          this.$emit('change', dataUrl)
        })
      }, DEBOUNCE_TIME),
    },
  },
  mounted() {
    this.createPdf()
  },
}
</script>
<style>
.vue-pdfmake-container * {
  display: block;
  color: #000000;
  padding: 0 !important;
  margin: 0;
}
.vue-pdfmake-container a {
  text-decoration: none;
}
</style>

Leave a Reply