123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- <template>
- <div class="reportBox">
- <div class="outlineBox">
- <div class="btnBox">
- <el-dropdown
- trigger="click"
- @command="callFn"
- popper-class="psarDropdown"
- >
- <el-button style="color: #05bb4c" size="small" type="text"
- >导出
- <el-icon><arrow-down /></el-icon>
- </el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item command="exportPDF">PDF</el-dropdown-item>
- <el-dropdown-item command="exportWord">WORD</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- <!-- <el-button type="success" size="mini" @click="exportPDF"
- >导出PDF</el-button
- > -->
- </div>
- <template v-if="reportTitle">
- <p
- class="songti font fw"
- style="
- width: 100%;
- padding: 12px 24px;
- color: #b3bdc0;
- background: rgba(96, 103, 105, 0.2);
- cursor: pointer;
- margin: 0;
- color: #05bb4c;
- "
- @click="
- nodeClick({
- label: `国家能源集团宁夏新能源开发有限公司${reportTitle}`,
- })
- "
- >
- {{ reportTitle }}
- </p>
- </template>
- <el-tree
- :data="treeData"
- :props="{
- children: 'children',
- label: 'label',
- }"
- style="height: calc(100% - 48px); overflow-y: scroll"
- @node-click="nodeClick"
- >
- <template #default="{ node, data }">
- <span class="font songti fw">{{ data.index }}{{ node.label }}</span>
- </template>
- </el-tree>
- </div>
- <div class="resizeLine">
- <el-divider direction="vertical" />
- <el-icon :size="24" color="#eee"><DCaret /></el-icon>
- </div>
- <div class="contentBox">
- <div class="pagePadding A4">
- <div class="page">
- <template v-if="reportTitle">
- <h1
- :id="`国家能源集团宁夏新能源开发有限公司${reportTitle}`"
- class="songti mainTitle fw"
- style="margin-bottom: 0"
- >
- 国家能源集团宁夏新能源开发有限公司
- </h1>
- <h1 :id="reportTitle" class="songti mainTitle fw">
- {{ reportTitle }}
- </h1>
- </template>
- <el-card
- :id="pItem.label"
- v-for="pItem in treeData"
- :key="pItem.index"
- >
- <p class="songti title fw">
- {{ pItem.index || "" }}{{ pItem.label }}
- </p>
- <p
- class="fangsong indent"
- style="margin-bottom: 5px"
- v-for="(cItem, cIndex) in pItem.content"
- :key="cIndex"
- >
- {{ cItem }}
- </p>
- </el-card>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import Get_PDF from "@tools/fixGetPDF";
- import docxtemplater from "docxtemplater";
- import { saveAs } from "file-saver";
- import JSZipUtils from "jszip-utils";
- import PizZip from "pizzip";
- export default {
- components: {},
- data() {
- return {
- locationHref: "",
- reportTitle: "",
- treeData: [
- {
- label: "发电量完成情况",
- children: [],
- content: [],
- },
- {
- label: "资源及理论发电量平衡分析",
- children: [],
- content: [],
- },
- {
- label: "电网调度因素损失分析",
- children: [],
- content: [],
- },
- {
- label: "故障及损失分析",
- children: [],
- content: [],
- },
- {
- label: "计划检修损失分析",
- children: [],
- content: [],
- },
- {
- label: "性能损失分析",
- children: [],
- content: [],
- },
- {
- label: "厂用电量分析",
- children: [],
- content: [],
- },
- {
- label: "场站问题总结和建议",
- children: [],
- content: [],
- },
- ],
- sourceData: {},
- };
- },
- created() {
- this.locationHref = location.href;
- let treeData = this.initTreeData(this.BASE.deepCopy(this.treeData || []));
- this.treeData = treeData;
- },
- mounted() {
- this.$nextTick(() => {
- this.initMouseEvent();
- this.getContentData();
- if (this.$route.hash) {
- this.pageScroll(this.$route.hash.replace(/^\#/, ""));
- }
- });
- },
- methods: {
- // 初始化树形
- initTreeData(treeData, parentIdx = "") {
- treeData.forEach((ele, idx) => {
- ele.index = `${parentIdx}${idx + 1}.`;
- if (ele.children?.length) {
- return this.initTreeData(ele.children, ele.index);
- }
- });
- return treeData;
- },
- // 初始化鼠标事件
- initMouseEvent() {
- const resize = document.querySelector(".resizeLine");
- const left = document.querySelector(".outlineBox");
- const right = document.querySelector(".contentBox");
- const box = document.querySelector(".reportBox");
- const svgPath = resize.querySelector(".el-icon path");
- left.style.width = getComputedStyle(left, null).width;
- right.style.width = getComputedStyle(right, null).width;
- resize.onmousedown = (e) => {
- const startX = e.clientX;
- resize.left = resize.offsetLeft;
- svgPath.style.fill = "#05bb4c";
- svgPath.style.transform = "scale(1.5)";
- svgPath.style.transformOrigin = "center center";
- svgPath.style.transition = "0.2s";
- document.onmousemove = (e) => {
- var endX = e.clientX;
- const maxT = box.clientWidth - resize.offsetWidth;
- let moveLen = resize.left + (endX - startX);
- if (moveLen < 250) moveLen = 250;
- if (moveLen > maxT - 1000) moveLen = maxT - 1000;
- resize.style.left = moveLen;
- left.style.width = `${moveLen}px`;
- right.style.width = `${box.clientWidth - moveLen - 8}px`;
- };
- document.onmouseup = () => {
- svgPath.style.fill = "#eee";
- svgPath.style.transform = "scale(1)";
- svgPath.style.transformOrigin = "center center";
- svgPath.style.transition = "0.2s";
- document.onmousemove = null;
- document.onmouseup = null;
- resize.releaseCapture && resize.releaseCapture();
- };
- resize.setCapture && resize.setCapture();
- return false;
- };
- },
- // 树形点击
- nodeClick(node) {
- const label = node.label;
- location.hash = `${this.$route.path}#${label}`;
- this.pageScroll(label);
- },
- // 页面滚动至锚点
- pageScroll(id) {
- document.getElementById(id)?.scrollIntoView({ behavior: "smooth" });
- },
- // 数据请求
- getContentData() {
- const that = this;
- that.API.requestData({
- isMust: false, // 请求是否携带 token ,默认为 true ,可缺省
- showLoading: true, // 请求是否显示加载中遮罩层,默认 false ,可缺省
- method: "GET", // 请求方式,默认为 GET ,可缺省
- baseURL: "http://192.168.10.9:9001/", // 请求服务器地址 + 端口,可缺省
- subUrl: "economy/analysis/2023/3", // 请求接口地址,必传项
- timeout: 3000, // 请求超时时间,默认 3s ,可缺省
- success({ data }) {
- that.sourceData = data;
- that.treeData.forEach((pEle) => {
- const content = data[pEle.label] || [];
- if (content.length) {
- content.forEach((cEle) => {
- pEle.content.push(cEle);
- });
- }
- });
- that.reportTitle = data?.["标题"]?.[0] || "";
- },
- });
- },
- // 下拉列表调用函数
- callFn(command) {
- this[command]();
- },
- // 导出 PDF
- exportPDF() {
- this.BASE.showLoading({
- text: "正在导出...请稍后...",
- });
- setTimeout(() => {
- Get_PDF.getPdf(
- document.querySelector(".contentBox .page"),
- "2023年3月经济运行分析报告"
- );
- this.BASE.closeLoading();
- }, 50);
- },
- // 导出 WORD
- exportWord() {
- let wordData = {};
- for (let key in this.sourceData) {
- if (key === "标题") {
- wordData[key] = this.sourceData[key][0];
- } else {
- let dataItem = [];
- this.sourceData[key].forEach((content) => {
- dataItem.push({ content });
- });
- wordData[key] = dataItem;
- }
- }
- // 读取并获得模板文件的二进制内容
- JSZipUtils.getBinaryContent(
- "./static/template/wordTemplate.docx",
- function (error, content) {
- if (error) {
- throw error;
- }
- // 创建一个PizZip实例,内容为模板的内容
- let zip = new PizZip(content);
- // 创建并加载docxtemplater实例对象
- let doc = new docxtemplater(zip, { linebreaks: true });
- // doc.attachModule(new ImageModule(opts));
- doc.setData(wordData);
- try {
- // 用模板变量的值替换所有模板变量
- doc.render();
- } catch (error) {
- // 抛出异常
- let e = {
- message: error.message,
- name: error.name,
- stack: error.stack,
- properties: error.properties,
- };
- throw error;
- }
- // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
- let out = doc.getZip().generate({
- type: "blob",
- mimeType:
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
- });
- // 将目标文件对象保存为目标类型的文件,并命名
- saveAs(out, "2023年3月经济运行分析报告.docx");
- }
- );
- },
- },
- watch: {},
- };
- </script>
- <style lang="less" scoped>
- .reportBox {
- width: 100%;
- height: 100%;
- overflow: hidden;
- .outlineBox {
- width: calc(25% - 8px);
- height: 100%;
- float: left;
- .btnBox {
- width: 97%;
- margin: 0 1.5% 12px 1.5%;
- display: flex;
- justify-content: flex-end;
- align-items: center;
- }
- }
- .resizeLine {
- width: 6px;
- height: 100%;
- cursor: w-resize;
- float: left;
- position: relative;
- .el-icon {
- position: absolute;
- left: calc(50% - 12px);
- top: calc(50% - 12px);
- transform: rotate(90deg);
- transition: 0.2s;
- }
- .el-divider--vertical {
- width: 2px;
- margin: 0 2px;
- height: 100%;
- transition: 0.2s;
- }
- &:active .el-divider--vertical {
- background: #05bb4c;
- transition: 0.2s;
- }
- }
- .contentBox {
- float: right;
- width: 75%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: flex-start;
- overflow-y: scroll;
- .mainTitle {
- font-size: 30px;
- width: 90%;
- margin: 0 5% 20px 5%;
- text-align: center;
- color: #000;
- }
- .page {
- background: #fff;
- }
- .pagePadding {
- padding: 20mm;
- box-sizing: border-box;
- background: #fff;
- }
- .A4 {
- width: 210mm;
- }
- .el-card {
- border-color: transparent;
- color: #000;
- .el-card__body {
- p {
- margin: 0;
- }
- }
- }
- }
- }
- .font {
- width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- line-height: 1.5;
- }
- .fw {
- font-weight: 700;
- }
- .songti {
- font-family: SimSun, 宋体;
- font-size: 18.7px;
- line-height: 2;
- }
- .fangsong {
- font-family: FangSong, 仿宋;
- font-size: 18.7px;
- line-height: 2;
- }
- .indent {
- text-indent: 2em;
- }
- .title {
- font-size: 22px;
- line-height: 2;
- }
- </style>
- <style lang="less">
- .contentBox {
- .el-card {
- .el-card__body {
- padding: 0;
- }
- }
- .el-card.is-always-shadow {
- box-shadow: none;
- }
- }
- .el-popper.is-light.psarDropdown {
- background: rgb(22, 30, 30);
- border: 1px solid #05bb4c;
- .el-scrollbar__wrap > ul {
- padding: 0;
- }
- .el-dropdown-menu {
- padding: 0;
- background: none;
- }
- .el-dropdown-menu__item {
- color: #fff;
- }
- .el-dropdown-menu__item:hover {
- color: #05bb4c;
- }
- .el-popper__arrow {
- &::before {
- border-top-color: #05bb4c !important;
- border-left-color: #05bb4c !important;
- }
- }
- }
- </style>
|