如何以二开的方式引出Excel并自定义样式

栏目:云苍穹知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

如何以二开的方式引出Excel并自定义样式

小编有话说



在客户的实际业务中,经常需要引出报表或动态表单的数据,并且对引出数据的表格样式有个性化需求,比如添加标题行、调整单元格高度、单元格背景色、文字字体/颜色/字号等等。目前苍穹提供的报表引出插件暂不支持引出表格个性化样式的实现。


因此,本篇文章介绍如何通过纯二开的方式,帮助客户实现引出表格数据的个性化样式需求




1 案例背景


客户系统有两张单据:水果单化肥单,需要把这两张单据的数据引出到Excel表格中。

水果单据的关键字段有【产品类型】(下拉列表)、【产地】(基础资料)、【水果名称】(单据体文本),如下图所示:


上传图片

图1-水果单据示例


化肥单据的关键字段有【肥料名称】(文本)、【产地】(基础资料),如下图所示:


上传图片

图2-化肥单据示例


两张单据的列表数据如下:


上传图片

图3-水果列表数据示例


上传图片

图4-化肥列表数据示例


报表和引出数据都需要对2张单据进行查询,需要实现引出的效果如下:


上传图片

图5-报表实现按钮示例


上传图片

图6-引出Excel示例


2 解决方案

2.1 方案整体思路


在这个方案的设计过程中,报表和引出数据都需要对2张单据进行查询,并利用文件服务提供下载功能。


同时,把查询和引出的代码与报表插件剥离,放到工具类中,做到代码复用,方便后续将该方案迁移到其他业务场景中使用。


整体二开流程如下:


1. 新建报表页面,设计报表,注册报表插件

2. 抽取查询数据公共代码,编写查询数据工具类

3. 编写报表取数插件,查询数据展示在报表上;

4. 编写报表界面插件,实现引出Excel文件,并修改Excel样式。


2.2 二开步骤详解


步骤1:新建报表页面,注册报表取数插件和报表页面插件


在【开发平台】表单设计器中,设计报表页面,并注册报表取数插件报表页面插件,如下图所示:


上传图片

图7-设计报表列表字段

上传图片

图8-注册报表取数插件

上传图片

图9-注册报表页面插件


步骤2:编写查询数据工具类


查询数据的代码,是引出的数据源,同时也是报表的数据源,这一部分的逻辑写在一个工具类中,共用代码。


使用QueryServiceHelper查询数据,将2个DateSet对象用join进行合并,代码如下:


public class FPQueryUtil {
    public static DataSet queryData() {
        DataSet dataSetFruits = QueryServiceHelper.queryDataSet("FruitPro", "kdec_fruit_bill",
                "id, billno as kdec_fnumber, kdec_entryentity.kdec_fruits as kdec_fname, kdec_fruit_type, kdec_fruit_pro.id as proid, kdec_fruit_pro.name as kdec_pro", null, "");
        DataSet dataSet2 = dataSetFruits.copy();
        Iterator<Row> iterator = dataSet2.iterator();
        List proList = new ArrayList<>();
        while (iterator.hasNext()) {
            Row row = iterator.next();
            proList.add(row.get("proid"));
        }
        QFilter regionFilter = new QFilter("kdec_region", QCP.in, proList);
        QFilter statusFilter = new QFilter("billstatus", QCP.like, "C");
        DataSet dataSetFertilizer = QueryServiceHelper.queryDataSet("FruitPro", "kdec_fertilizer_bill",
                "id, billno as kdec_fernumber, kdec_name as kdec_fername, kdec_region", new QFilter[]{regionFilter,statusFilter}, "");
        DataSet result = dataSetFruits.rightJoin(dataSetFertilizer)
                .select(new String[]{"kdec_fnumber", "kdec_fname", "kdec_pro", "kdec_fruit_type"}, new String[]{"kdec_fernumber", "kdec_fername"})
                .on("proid", "kdec_region").finish();
        return result;
    }
}



步骤3:编写报表取数插件


报表取数插件实现代码如下:


public class FruitProReportListDataPlugin extends AbstractReportListDataPlugin {
    @Override
    public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {
        return FPQueryUtil.queryData();
    }
}


步骤4:编写报表界面插件,引出Excel文件并修改样式


首先,监听按钮点击。调用以下代码,查询数据,构建Excel文件,弹出下载链接。代码如下:


@Override
public void itemClick(ItemClickEvent evt) {
    super.itemClick(evt);
    switch (evt.getItemKey()) {
        case "kdec_export": {
            // 第一行标题
            String title = "水果生产以及产地";
            // 调用查询工具类,获取数据源对象DataSet
            DataSet dataSet = FPQueryUtil.queryData();
            // excelList用于提供数据源给 excel工作簿,外层的list是行,里面的List<String>是列,存储value
            List<List<String>> excelList = getExcelList(dataSet);
            // 创建excel工作簿
            XSSFWorkbook workbook = MyExportUtil.reportExcel(excelList, title);
            // 上传
            String path = MyExportUtil.upload(title, workbook);
            // 弹出提示框
            getView().showMessage("下载文件链接:"+ RequestContext.get().getClientFullContextPath() + "/attachment/download.do?path=" + path);
        }
        break;
    }
}



接着,解析DataSet,构建数据集合构建第二行表头,解析DataSet,构建List对象,为即将引出的excel提供数据源,代码如下:


public List<List<String>> getExcelList (DataSet dataSet) {
    // excelList用于提供数据源给 excel工作簿,外层的list是行,里面的List<String>是列,存储value
    List<List<String>> excelList = new ArrayList<>();
    List<String> titles = new ArrayList<>();
    titles.add("水果编码");
    titles.add("水果名称");
    titles.add("产地");
    titles.add("化肥编码");
    titles.add("化肥名称");
    excelList.add(titles);
    while (dataSet.hasNext()) {
        Row row = dataSet.next();
        List<String> strings = new ArrayList<>();
        for ( int j = 0; j < row.size(); j++) {
            String value = row.getString(j);
            strings.add(value);
        }
        excelList.add(strings);
    }
    return excelList;
}



随后,构造XSSFWorkbook。创建XSSFWorkbook对象和XSSFSheet工作表对象,将上一步的数据源填充进XSSFWorkbook,代码如下:


public static XSSFWorkbook reportExcel(List<List<String>> excelList, String title) {
//创建excel工作簿
XSSFWorkbook workbook = new XSSFWorkbook();
//创建工作表sheet
XSSFSheet sheet = workbook.createSheet();
// 创建标题
XSSFRow headRow = sheet.createRow(0);
XSSFCell headCell = headRow.createCell(0);
// 设置标题的值
headCell.setCellValue(title);
// 合并第1行的前几列,合并列数 = excel的列数
CellRangeAddress titleCellAddresses = new CellRangeAddress(0, 0, 0, excelList.get(0).size()-1);
sheet.addMergedRegion(titleCellAddresses);
//写入单据列表数据
for (int i = 0; i < excelList.size(); i++) {
    // i+1是因为前面第1行加了一个标题,单据列表数据是从Excel的第2行开始的,所以要+1
    XSSFRow nrow = sheet.createRow(i + 1);
    for (int u = 0; u < excelList.get(i).size(); u++) {
        XSSFCell ncell = nrow.createCell(u);
        ncell.setCellStyle(billStyle);
        ncell.setCellValue(excelList.get(i).get(u));
    }
}
}



然后,调整表格的样式。为excel单元格设置背景、字颜色、字体等样式。感兴趣的开发者可以自行在csdn、百度等网站搜索XSSFCell的用法。部分代码如下:


//设置整个表格的默认列宽
sheet.setDefaultColumnWidth(20);
// 设置首行标题的一些风格样式
XSSFCellStyle titleStyle = workbook.createCellStyle();
// 设置背景色
//设置填充方案
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);;
// 设置自定义填充颜色,天蓝色
titleStyle.setFillForegroundColor(new XSSFColor(new Color(135,206,250)));
// 设置水平居中
titleStyle.setAlignment(HorizontalAlignment.CENTER);
// 设置垂直居中
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置字
XSSFFont font = workbook.createFont();
// 字体颜色橘红色
font.setColor(new XSSFColor(new Color(255 ,69,0)));
// 设置字号
font.setFontHeight(20);
// 设置字体
font.setFontName("黑体");
titleStyle.setFont(font);
// 设置标题行单元格的Style
headCell.setCellStyle(titleStyle);
// 普通单元格的style
// 单据列表数据风格样式,设置字体为黑体,字号15
XSSFCellStyle billStyle = workbook.createCellStyle();
// 设置背景色以及填充方案
billStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
billStyle.setFillForegroundColor(new XSSFColor(new Color(220,220,220)));
// 设置字体
XSSFFont billFont = workbook.createFont();
billFont.setFontName("宋体");
billFont.setFontHeight(15);
billStyle.setFont(billFont);
// 在循环体中,XSSFCell对象调用setCellStyle方法,将billStyle设置给每一个单元格


调整好表格样式后,使用文件服务上传文件调用文件服务上传之后,会有一个path返回,代码如下:


public static String upload (String entityName, XSSFWorkbook workbook) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
    String fileName = entityName + sdf.format(new Date()) + ".xlsx";
    String pathName = "/offices/" + fileName;
    try {
        OutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        InputStream inputStream = parse(outputStream);
        FileService fs = FileServiceFactory.getAttachmentFileService();
        String path = fs.upload(new FileItem(fileName, pathName, inputStream));
        return path;
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
    return "";
}
public static ByteArrayInputStream parse(final OutputStream out) throws Exception {
    ByteArrayOutputStream baos = (ByteArrayOutputStream) out;
    final ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
    return swapStream;
}



最后,拼接下载链接。将上一步返回的path对象进行拼接,可以得到文件下载链接,代码如下:


String downloadUrl = RequestContext.get().getClientFullContextPath() + "/attachment/download.do?path=" + path;


注意:如果需要直接下载链接,可以用openUrl方法,在浏览器中打开新页签,访问下载链接,这样浏览器就会直接下载这个Excel文件,代码如下:


getView().openUrl(downloadUrl);

2.3 效果展示


完成上述二开流程后,即可引出Excel并自定义样式,效果如下图所示:


上传图片

图10-报表引出按钮效果

上传图片

图11-文件下载提示

上传图片

图12-文件下载成功

上传图片

图13-引出Excel效果


3 方案价值


1. 此方案实现了客户的引出数据业务需求

2. 查询和引出的代码与报表插件剥离,放到工具类中,做到代码复用


4 常见问题


在上传时,如遇到了异常抛出,文件服务拒绝连接的场景,可以从以下方向排查问题:


  • 检查文件服务的磁盘容量是否超出上限,尝试删除上传路径的部分文件,看看能否解决问题。

  • 检查文件服务是否在运行,尝试重启文件服务

  • 检查服务端和客户端的端口号是否正确,默认是8100


上传图片

图14-异常抛出示例


5 相关资料


如需下载本方案相关补丁包Java源代码,可下载原帖文末附件:

如何实现在引出时修改单据列表引出数据和Excel字体样式


6 划重点


以二开的方式引出Excel并自定义样式的流程如下:


1. 新建报表页面,设计报表,注册报表插件

2. 抽取查询数据公共代码,编写查询数据工具类

3. 编写报表取数插件,查询数据展示在报表上;

4. 编写报表界面插件,实现引出Excel文件,并修改Excel样式。




#往期推荐#


# 苍穹调度:搞定你的定时业务功能

追光者大赛作品 之 UE典型优化场景介绍

手把手教你实现“树形单据”列表

元数据升级失败怎么办?排查指南速看!


更多精彩内容,“码”上了解!↓


上传图片


如何以二开的方式引出Excel并自定义样式

小编有话说在客户的实际业务中,经常需要引出报表或动态表单的数据,并且对引出数据的表格样式有个性化需求,比如添加标题行、调整单元格高...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息