刘光辉
11 小时以前 0dfe84494048ce27ba8449831782128412d3eb13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<script lang="ts" setup>
  import { nextTick, onMounted, onUnmounted, reactive, ref, toRefs, unref } from 'vue';
 
  import { JnpfSheetsPrintUiService } from '../../../Design/univer/services/sheet-print-ui.service';
  import { printA4PaperHeight, printA4PaperWidth } from '../../../Design/univer/utils/define';
 
  const props = defineProps(['jnpfUniverApi', 'pageLayout', 'printConfig', 'watermarkConfig']);
  const emits = defineEmits(['pageRendered']);
 
  // ✅ 页面容器引用
  const pageContainerRef = ref<HTMLElement | null>(null);
  const defaultContainerStyle = {
    height: printA4PaperHeight,
    width: printA4PaperWidth,
  };
 
  const state = reactive<{
    containerStyle: any;
    renderInstance: any;
  }>({
    containerStyle: defaultContainerStyle,
    renderInstance: null,
  });
  const { containerStyle } = toRefs(state);
 
  onMounted(() => {
    const { jnpfUniverApi, pageLayout = {}, printConfig = {}, watermarkConfig = {} } = props ?? {};
 
    const accessor = jnpfUniverApi?.getInjector();
    if (!accessor) {
      return;
    }
 
    const { paperSize = {} } = pageLayout;
    const containerScale = countContainerScale(paperSize); // 打印预览容器的伸缩比
 
    state.renderInstance = new JnpfSheetsPrintUiService(accessor, pageLayout, printConfig, watermarkConfig, containerScale);
    if (!state.renderInstance) {
      return;
    }
 
    const { h: paperSizeHeight = printA4PaperHeight, w: paperSizeWidth = printA4PaperWidth } = paperSize;
    state.containerStyle = {
      height: `${paperSizeHeight * containerScale}px`,
      width: `${paperSizeWidth * containerScale}px`,
    };
 
    state.renderInstance.container.style.cssText = 'width: 100%; height: 100%;';
 
    nextTick(() => {
      unref(pageContainerRef)?.append(state.renderInstance.container);
      state.renderInstance.container.append(state.renderInstance.root);
      state.renderInstance?.setDirty(true); // 设置脏状态(用于调整视口大小和滚动值的状态)
      state.renderInstance?.renderPage(); // 渲染页面
      state.renderInstance?.renderOnReady(); // 主要是在页面变换时确保页面内容的及时更新,并且做了订阅和销毁的管理。
      emits('pageRendered');
    });
  });
 
  onUnmounted(async () => {
    await state.renderInstance?.dispose();
 
    state.renderInstance = null;
    state.containerStyle = defaultContainerStyle;
  });
 
  // 计算打印预览容器的伸缩比
  function countContainerScale(paperSize: any) {
    const { w = printA4PaperWidth } = paperSize;
 
    return Math.round((printA4PaperWidth / w) * 10) / 10;
  }
</script>
 
<template>
  <div ref="pageContainerRef" :style="containerStyle" class="print-page-container"></div>
</template>
 
<style lang="scss">
  .print-page-container {
    position: relative;
    flex: 0 0 auto;
    margin: 28px auto;
    background-color: #fff;
    box-shadow: 0 4px 24px 0 rgb(30 34 43 / 8%);
  }
</style>