ExportPDF.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <div class="export-pdf-dialog">
  3. <div class="thumbnails-view">
  4. <div class="thumbnails" ref="pdfThumbnailsRef">
  5. <ThumbnailSlide
  6. class="thumbnail"
  7. :slide="currentSlide"
  8. :size="1600"
  9. v-if="rangeType === 'current'"
  10. />
  11. <template v-else>
  12. <ThumbnailSlide
  13. class="thumbnail"
  14. :class="{ 'break-page': (index + 1) % count === 0 }"
  15. v-for="(slide, index) in slides"
  16. :key="slide.id"
  17. :slide="slide"
  18. :size="1600"
  19. />
  20. </template>
  21. </div>
  22. </div>
  23. <div class="configs" :style="{ width: lang.lang === 'en' ? '475px' : '350px' }">
  24. <div class="row">
  25. <div class="title">{{ lang.ssExpRange }}</div>
  26. <RadioGroup
  27. class="config-item"
  28. v-model:value="rangeType"
  29. >
  30. <RadioButton style="width: 50%;" value="all">{{ lang.ssShowAll }}</RadioButton>
  31. <RadioButton style="width: 50%;" value="current">{{ lang.ssCurPage }}</RadioButton>
  32. </RadioGroup>
  33. </div>
  34. <div class="row">
  35. <div class="title">{{ lang.ssPerPage }}</div>
  36. <Select
  37. class="config-item"
  38. v-model:value="count"
  39. :options="[
  40. { label: '1', value: 1 },
  41. { label: '2', value: 2 },
  42. { label: '3', value: 3 },
  43. ]"
  44. />
  45. </div>
  46. <div class="row">
  47. <div class="title">{{ lang.ssEdgePad }}</div>
  48. <div class="config-item">
  49. <Switch v-model:value="padding" />
  50. </div>
  51. </div>
  52. <div class="tip">
  53. {{ lang.ssPrintBgTip }}
  54. </div>
  55. </div>
  56. <div class="btns">
  57. <Button class="btn export" type="primary" @click="expPDF()">{{ lang.ssPrintPdf }}</Button>
  58. <Button class="btn close" @click="emit('close')">{{ lang.ssClose }}</Button>
  59. </div>
  60. </div>
  61. </template>
  62. <script lang="ts" setup>
  63. import { ref, useTemplateRef } from 'vue'
  64. import { storeToRefs } from 'pinia'
  65. import { useSlidesStore } from '@/store'
  66. import { print } from '@/utils/print'
  67. import { lang } from '@/main'
  68. import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue'
  69. import Switch from '@/components/Switch.vue'
  70. import Button from '@/components/Button.vue'
  71. import RadioButton from '@/components/RadioButton.vue'
  72. import RadioGroup from '@/components/RadioGroup.vue'
  73. import Select from '@/components/Select.vue'
  74. const emit = defineEmits<{
  75. (event: 'close'): void
  76. }>()
  77. const { slides, currentSlide, viewportRatio } = storeToRefs(useSlidesStore())
  78. const pdfThumbnailsRef = useTemplateRef<HTMLElement>('pdfThumbnailsRef')
  79. const rangeType = ref<'all' | 'current'>('all')
  80. const count = ref(1)
  81. const padding = ref(true)
  82. const expPDF = () => {
  83. if (!pdfThumbnailsRef.value) return
  84. const pageSize = {
  85. width: 1600,
  86. height: rangeType.value === 'all' ? 1600 * viewportRatio.value * count.value : 1600 * viewportRatio.value,
  87. margin: padding.value ? 50 : 0,
  88. }
  89. print(pdfThumbnailsRef.value, pageSize)
  90. }
  91. </script>
  92. <style lang="scss" scoped>
  93. .export-pdf-dialog {
  94. height: 100%;
  95. display: flex;
  96. justify-content: center;
  97. align-items: center;
  98. flex-direction: column;
  99. position: relative;
  100. overflow: hidden;
  101. }
  102. .thumbnails-view {
  103. @include absolute-0();
  104. &::after {
  105. content: '';
  106. background-color: #fff;
  107. @include absolute-0();
  108. }
  109. }
  110. .thumbnail {
  111. &.break-page {
  112. break-after: page;
  113. }
  114. }
  115. .configs {
  116. width: 300px;
  117. height: calc(100% - 80px);
  118. display: flex;
  119. flex-direction: column;
  120. justify-content: center;
  121. z-index: 1;
  122. .row {
  123. display: flex;
  124. justify-content: center;
  125. align-items: center;
  126. margin-bottom: 25px;
  127. }
  128. .title {
  129. width: 100px;
  130. }
  131. .config-item {
  132. flex: 1;
  133. }
  134. .tip {
  135. font-size: 12px;
  136. color: #aaa;
  137. line-height: 1.8;
  138. margin-top: 25px;
  139. }
  140. }
  141. .btns {
  142. width: 300px;
  143. height: 80px;
  144. display: flex;
  145. justify-content: center;
  146. align-items: center;
  147. z-index: 1;
  148. .export {
  149. flex: 1;
  150. }
  151. .close {
  152. width: 100px;
  153. margin-left: 10px;
  154. }
  155. }
  156. </style>