dexteryao 发表于 2020-8-31 23:23:31

SpreadJS 全家桶实践 - 在线Excel报表系统(三)

本帖最后由 dexteryao 于 2020-8-31 23:23 编辑

前两期
SpreadJS 全家桶实践 - 在线Excel报表系统(一)
SpreadJS 全家桶实践 - 在线Excel报表系统(二)
实现了报表设计和数据绑定,本期将继续实现页面设置和导出PDF功能

为了导出PDF分页符合预期,进行简单的页面设置
新建ribbon.print.js添加页面配置config,并且在designer.js中 initDesigner方法里配置

    customerRibbon.buttonGroups.push(ribbonPrintConfig)

ribbon.print.js内容

var ribbonPrintConfig = {
    "label": "页面布局",
    "thumbnailClass": "ribbon-thumbnail-spreadsettings",
    "commandGroup": {
      "children": [
            {
                "direction": "vertical",
                "commands": [
                  {
                        text: "打印分页预览线",
                        type: "checkbox",
                        commandName: "show_hide_print_line",
                        execute: async (context) => {
                            setTimeout(() => {
                              let sheet = context.Spread.getActiveSheet();
                              var isVisible = sheet.isPrintLineVisible();
                              sheet.isPrintLineVisible(!isVisible);
                            }, 0)
                        },
                        getState: (context) => {
                            let sheet = context.Spread.getActiveSheet();
                            return sheet.isPrintLineVisible();
                        }
                  }
                ]
            },
            {
                "type": "separator"
            },
            {
                "direction": "vertical",
                "commands": [
                  {
                        iconClass: "ribbon-button-namemanager",
                        text: "插入分页符",
                        commandName: "insertPageBreak",
                        execute: async (context) => {
                            let sheet = context.Spread.getActiveSheet();
                            sheet.setColumnPageBreak(sheet.getActiveColumnIndex(), true)
                            sheet.setRowPageBreak(sheet.getActiveRowIndex(), true)
                        }
                  },
                  {
                        iconClass: "ribbon-button-namemanager",
                        text: "删除分页符",
                        commandName: "deletePageBreak",
                        execute: async (context) => {
                            let sheet = context.Spread.getActiveSheet();
                            sheet.setColumnPageBreak(sheet.getActiveColumnIndex(), false)
                            sheet.setRowPageBreak(sheet.getActiveRowIndex(), false)
                        }
                  },
                  {
                        iconClass: "ribbon-button-namemanager",
                        text: "删除所有分页符",
                        commandName: "deleteAllPageBreak",
                        execute: async (context) => {
                            let sheet = context.Spread.getActiveSheet();
                            sheet.suspendPaint()
                            for(var row = 0; row < sheet.getRowCount(); row++){
                              sheet.setRowPageBreak(row, false)
                            }
                            for(var col = 0; col < sheet.getColumnCount(); col++){
                              sheet.setColumnPageBreak(col, false)
                            }
                            sheet.resumePaint();
                        }
                  },
                ]
            },
            {
                "type": "separator"
            },
            {
                "direction": "vertical",
                "commands": [
                  {
                        iconClass: "ribbon-button-namemanager",
                        text: "宽度",
                  },
                  {
                        iconClass: "ribbon-button-namemanager",
                        text: "高度",
                  }
                ]
            },
            {
                "direction": "vertical",
                "commands": [
                  {
                        text: "自动",
                        type: "combobox",
                        commandName: "setFitPagesWide",
                        dropdownList: [
                            {
                              text: "自动",
                              value: "-1"
                            },
                            {
                              text: "1",
                              value: "1"
                            },
                            {
                              text: "2",
                              value: "2"
                            }
                        ],
                        execute: async (context, selectValue) => {
                            if (selectValue != null && selectValue != undefined) {
                              setTimeout(() => {
                                    let sheet = context.Spread.getActiveSheet();
                                    var printInfo = sheet.printInfo();
                                    printInfo.fitPagesWide(parseInt(selectValue));
                                    sheet.printInfo(printInfo)
                              }, 0);
                            }
                        },
                        getState: (context) => {
                            let sheet = context.Spread.getActiveSheet();
                            var printInfo = sheet.printInfo()
                            var value = printInfo.fitPagesWide();
                            return value.toString();
                        }

                  },
                  {
                        text: "高度",
                        type: "combobox",
                        commandName: "setFitPagesTall",
                        dropdownList: [
                            {
                              text: "自动",
                              value: "-1"
                            },
                            {
                              text: "1",
                              value: "1"
                            },
                            {
                              text: "2",
                              value: "2"
                            }
                        ],
                        execute: async (context, selectValue) => {
                            if (selectValue != null && selectValue != undefined) {
                              setTimeout(() => {
                                    let sheet = context.Spread.getActiveSheet();
                                    var printInfo = sheet.printInfo();
                                    printInfo.fitPagesTall(parseInt(selectValue));
                                    sheet.printInfo(printInfo)
                              }, 0);
                            }
                        },
                        getState: (context) => {
                            let sheet = context.Spread.getActiveSheet();
                            var printInfo = sheet.printInfo()
                            var value = printInfo.fitPagesTall();
                            return value.toString();
                        }

                  }
                ]
            }
      ]
    }
};

添加导出PDF按钮和下拉选项,按钮样式为自定义图标{
                "commands": [
                  {
                        iconClass: "ribbon-button-pdf-font",
                        bigButton: true,
                        text: "PDF",
                        commandName: "pdf0",
                        execute: exportPDF,
                  },
                  {
                        title: "PDF_List",
                        type: "dropdown",
                        commandName: "pdf_sub",
                        subCommands: [
                            {
                              text: "绑定数据导出",
                              iconClass: "ribbon-button-pdf-small",
                              commandName: "pdf2",
                              execute: async (context, selectValue) => {
                                    await exportPDF(context, true);
                              }
                            },
                            {
                              text: "导出当前Sheet",
                              iconClass: "ribbon-button-pdf-small",
                              commandName: "pdf1",
                              execute: async (context, selectValue) => {
                                    await exportPDF(context, false, true);
                              }
                            },
                            {
                              text: "绑定导出当前Sheet",
                              iconClass: "ribbon-button-pdf-small",
                              commandName: "pdf3",
                              execute: async (context, selectValue) => {
                                    await exportPDF(context, true, true);
                              }
                            }
                        ]
                  }
                ]
            },根据点击不同按钮,exportPDF方法传递不同参数
async function exportPDF(designer, isBinding, isActiveSheet) {
    console.log(arguments)
    var spread = designer.getWorkbook();
    var spreadJSON = JSON.stringify(spread.toJSON());
    var uploadData = gzipString(spreadJSON);
    fetch("spread/getpdf", {
      body: "data=" + encodeURIComponent(uploadData) + "&isBinding=" + !!isBinding + "&isActiveSheet=" + !!isActiveSheet,
      headers: {
            "content-type": "application/x-www-form-urlencoded"
      },
      method: "POST"
    }).then(resp => resp.blob())
      .then(blob => {
            const url = window.URL.createObjectURL(blob);
            window.open(url, "_blank")
      })
}
服务端使用GCExcel 绑定数据,返回PDF,前端直接新tab 打开

    /* 导出PDF,可选择单sheet导出或者绑定模拟数据后导出*/
    @RequestMapping(value = "/getpdf", method = RequestMethod.POST)
    public ResponseEntity<byte[]> getPDF(@RequestParam(value = "data", required = true) String data,
                                       @RequestParam(value = "isBinding", required = false) boolean isBinding,
                                       @RequestParam(value = "isActiveSheet", required = false) boolean isActiveSheet) {

      String json = uncompress(data);
      Workbook workbook = new Workbook();
      List<com.grapecity.documents.excel.JsonError> errors = workbook.fromJson(json);
      System.out.println(errors);

      if (isBinding) {
            bindingDataToWrokbook(workbook);
      }

      System.out.println(workbook.getActiveSheet().getUsedRange(EnumSet.of(UsedRangeType.Data, UsedRangeType.DataValidation)));

      ByteArrayOutputStream out = new ByteArrayOutputStream();

      if (isActiveSheet) {
            IWorksheet sheet = workbook.getActiveSheet();
            System.out.println(sheet.getVPageBreaks().getCount());
            sheet.save(out, SaveFileFormat.Pdf);
      } else {
            workbook.save(out, SaveFileFormat.Pdf);
      }
//      System.out.print(workbook.toJson());

      byte[] contents = out.toByteArray();

      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.APPLICATION_PDF);
      // Here you have to set the actual filename of your pdf
      String filename = "output.pdf";
      headers.setContentDispositionFormData(filename, filename);
      headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
      ResponseEntity<byte[]> response = new ResponseEntity<>(contents, headers, HttpStatus.OK);
      return response;
    }
更多内容请关注葡萄城技术社区


页: [1]
查看完整版本: SpreadJS 全家桶实践 - 在线Excel报表系统(三)