[]
        
(Showing Draft Content)

数据源

概述

在使用GcExcel 报表模板生成报表的过程中,报表模板和数据源是同等重要的两部分。在制作模板时,模板字段中的数据字段需要数据源名字,数据字段名字。提前规划好数据源的结构,可以使得模板制作的过程更为高效。

在数据填充时,只需要将准备好的数据源通过 AddDataSource 方法添加至 Workbook 中,即可直接调用 ProcessTemplate 方法完成数据和模板的结合,生成报表。

数据源类型

GcExcel 模板功能时支持下面的数据源:

  • 结果集 (ResultSet)

  • 自定义对象 (Custom Object)

  • JsonDataSource

  • 变量 (Variable)

  • 数组或列表 (Array or List)

结果集 (ResultSet)

结果集是一张包含来自任何类型的数据库的行和列的集合的表。

模板字段语法:

image

示例:

  • {{ds.Table1.ID}}

  • {{ds.Table2.Team}}

相关代码:

// 在这个演示中,我们使用一个模拟类来生成java.sql.ResultSet的实例。  
// 在产品中使用模板的用户,必须从java.sql.ResultSet的  
// 相关数据库连接。 
java.sql.ResultSet datasource = new GcMockResultSet(this.getResourceStream("score.csv"));
 
// 添加数据源
workbook.addDataSource("ds", datasource);

自定义对象 (Custom Object)

代码中用户定义的对象,或者从 JSON String / JSON File / XML 反序列化的对象。GcExcel模板支持任何可以被反序列化成自定义对象的数据源。

模板语法:

image

示例:

  • {{ds.Records.Area}}

  • {{ds.Records.Product}}

相关代码:

NestedDataTemplate_Student student2 = new NestedDataTemplate_Student();
student2.name = "Mark";
student2.address = "101, Halford Avenue, Fremont, CA";
Family family3 = new Family();

family3.father = new Guardian();
family3.father.name = "Jonathan Williams";
family3.father.setOccupation("Product Engineer");
family3.mother = new Guardian();
family3.mother.name = "Joanna Williams";
family3.mother.setOccupation("Surgeon");

student2.family = new ArrayList();
student2.family.add(family3);
 
// 添加数据源
workbook.addDataSource("ds", student2);

自定义数据表

用户定义的自定义表是从任何类型的数据库中收集的行和列的集合。GcExcel 提供了 ITableDataSource 接口以简化自定义数据源的创建,并更高效地管理它们。

下表列出了 ITableDataSource 接口的所有成员:

成员

描述

getValue

基于行列坐标获取值

getRowCount

获取行的数量

getColumnCount

获取列的数量

getColumnName

根据列坐标获取列名

getColumnIndex

根据列名获取列坐标

模板语法:

image

示例:

  • {{customer.name}}

  • {{product.name}}

参考以下示例代码,使用一个将JSON流转换为结构化表格的类,从JSON流中创建自定义数据表:

public class CustomDataTable {

    public static void main(String[] args) throws Exception {
        // Initialize Workbook.
        Workbook workbook = new Workbook();
        
        // Open template file.
        workbook.open("ComplexMultiDataSource.xlsx");
        
        // Create table data sources from JSON.
        InputStream order_json;
        order_json = new FileInputStream("order.json");
        InputStream customer_json;
        customer_json = new FileInputStream("customer.json");
        InputStream product_json;
        product_json = new FileInputStream("product.json"); 
        JsonTable order = new JsonTable(order_json);
        JsonTable customer = new JsonTable(customer_json);
        JsonTable product = new JsonTable(product_json);
        
        // Add data sources for template.
        workbook.addDataSource("order", order);
        workbook.addDataSource("customer", customer);
        workbook.addDataSource("product", product);
        
         // Process the template.
        workbook.processTemplate();
        
        // Set column width.
        workbook.getWorksheets().get(0).getRange("A:F").setColumnWidth(16);
            
        // Save to an excel file
        workbook.save("CustomDataTable.xlsx");
    }
}

/*
The class is only part of the sample, not part of the product.
So it is not recommended to use this class in a production environment.
Please implement your own class that meets the requirements of the product.
*/
// Create a class to transform a JSON stream into a table and inherit ITableDataSource.
class JsonTable implements ITableDataSource {
    private final JsonArray _jsonArray;
    private final HashMap<Integer, String> _columnsMap;
    private final HashMap<String, Integer> _reversedColumnsMap;

    public JsonTable(InputStream inputStream) {
        String jsonContent;
        try {
            jsonContent = convertToString(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        _jsonArray = JsonParser.parseString(jsonContent).getAsJsonArray();
        JsonObject jsonObject = _jsonArray.get(0).getAsJsonObject();
        _columnsMap = new HashMap<>();
        _reversedColumnsMap = new HashMap<>();
        int index = 0;
        for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            String next = entry.getKey();
            _columnsMap.put(index, next);
            _reversedColumnsMap.put(next, index);
            index++;
        }
    }

    private String convertToString(InputStream inputStream) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }
        }
        return stringBuilder.toString();
    }

    // Get value from data source.
    @Override
    public Object getValue(int row, int column) {
        return _jsonArray.get(row).getAsJsonObject().get(_columnsMap.get(column)).getAsString();
    }

    // Get row count from data source.
    @Override
    public int getRowCount() {
        return _jsonArray.size();
    }

    // Get column count from data source.
    @Override
    public int getColumnCount() {
        return _columnsMap.size();
    }

    // Get column name from data source.
    @Override
    public String getColumnName(int column) {
        if (_columnsMap.containsKey(column)) {
            return _columnsMap.get(column);
        }
        return null;
    }

    // Get column index from data source.
    @Override
    public int getColumnIndex(String columnName) {
        if (_reversedColumnsMap.containsKey(columnName)) {
            return _reversedColumnsMap.get(columnName);
        }

        return -1;
    }
}

JsonDataSource

GcExcel 提供了一个 JsonDataSource 类,您可以通过传入 Json 文本来构建 JsonDataSource 对象,并以该对象为数据源进行绑定。

这样就无需创建映射类来从Json获取数据,可以直接使用Json的字段或成员来制作模板,如下面的模板语法所示:

模板语法:

image

示例:

  • {{ds.student.family.father.name}}

  • {{ds.student.family.father.occupation}}

  • {{ds.student.family.mother.name}}

示例JSON供参考:

student.json

image

相关代码:

//Get data from json file
String jsonText = "";
try {
    InputStream stream = getResourceStream("Template_FamilyInfo.json");

    ByteArrayOutputStream result = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length;
    while ((length = stream.read(buffer)) != -1) {
        result.write(buffer, 0, length);
    }

    jsonText = result.toString("UTF-8");
} catch (IOException e) {
    e.printStackTrace();
}

// Create a JsonDataSource
JsonDataSource datasource = new JsonDataSource(jsonText);

//Add data source
workbook.addDataSource("ds", datasource);

变量 (Variable)

代码中用户定义的变量。

模板语法:

image

示例:

  • {{cName}}

  • {{count}}

  • {{owner}}

相关代码:

String className = "Class 3";
int count = 500;
 
//Add data source
workbook.addDataSource("cName", datasource);
workbook.addDataSource("count", count);
workbook.addDataSource("owner", "Hunter Liu");

数组或列表 (Array or List)

代码中用户定义的数组或列表。

模板语法:

  1. 基本类型的数组或列表(字符串,整型,双精度浮点型等。):

    image


  2. 自定义对象类型的数组或列表:

    image

示例:

  • {{p.Name}}

  • {{p.Age}}

  • {{countries}}

  • {{numbers}}

相关代码:

int[] numbers = new int[] { 10, 12, 8, 15};
List countries = new List() { "USA", "Japan", "UK", "China" };
 
List peoples = new List();
 
Person p1 = new Person();
p1.Name = "Helen";
p1.Age = 12;
peoples.Add(p1);
 
Person p2 = new Person();
p2.Name = "Jack";
p2.Age = 23;
peoples.Add(p2);
 
Person p3 = new Person();
p3.Name = "Fancy";
p3.Age = 25;
peoples.Add(p3);
 
workbook.addDataSource("p", peoples);
workbook.addDataSource("countries", countries);
workbook.addDataSource("numbers", numbers);

type=info

此外,你也可以将多个数据源或者多个数据表整合到一个数据源中,并通过它们填充数据。该语法要求遵循数据字段来定义数据源对象。例如,下面的模板布局将两个数据源合并成了一个,雇员信息在一个数据表中,部门信息在另一个数据表中。

Multiple data sources