[]
GcExcel 支持通过指定的打开选项(如条件格式、合并区域、表格等)导入工作簿。
本节概述 GcExcel Java 处理电子表格文档(.xlsx 文件)的方法。
使用 GcExcel Java 创建并保存工作簿时,会自动将其导出至外部路径或文件夹。将 Excel 文件导入 GcExcel Java(即打开文件)时,既可以加载该电子表格的完整模型,也可以只导入数据。GcExcel Java 提供了 open 方法来打开文件,该方法可搭配多种导入标志使用,这些标志可通过 XlsxOpenOptions 类的 setImportFlags 方法进行配置。
同理,若要将工作簿导出为 .xlsx 文件,可使用 save 方法,并通过 GcExcel 提供的多种保存选项,指定导出内容和需要跳过的内容。具体选项如下表所示:
类名 | 属性 | 描述 | |
|---|---|---|---|
Import Options | 指定在打开Excel文件时是否自动调整行高。 | ||
指定在Excel文件打开后是否重新计算公式值。 | |||
提供各种标志以导入工作表的各个方面。有关更多信息。 | |||
指示是否以仅数字签名模式打开工作簿。在仅数字签名模式下,除非调用ISignature.Delete,否则现有签名将被保留。但在此模式下,您只能对现有签名行进行签名、添加不可见签名、移除已签名签名行的数字签名或移除不可见签名。其他更改将被丢弃。修改数字签名后,您需要保存工作簿以提交更改。若要以仅数字签名模式打开工作簿,则为True;否则,使用正常模式。默认值为false。 | |||
这个xlsx文件的密码。 | |||
表示工作簿打开时的格式。 | |||
Export Options | 将GcExcel工作表的公式单元格导出为Excel中的值单元格。 | ||
导出文件时,排除未使用的样式。 | |||
导出文件时,排除未使用的名称。 | |||
排除空单元格,即位于已使用区域之外、具有样式但不包含数据的单元格。 | |||
指示是否以紧凑模式保存工作簿。默认值为 false。 | |||
这个xlsx文件的密码。 | |||
指示是否包含自动合并的单元格。默认值为 false。 | |||
指示在保存文件时是否包含绑定源。默认值为true。 | |||
指定在保存工作簿时是否导出共享公式。默认值为true。 | |||
表示工作簿的保存格式。 | |||
以下示例代码展示了如何通过文件名导入和导出 .xlsx 文档:
// 创建一个新的工作簿
Workbook workbook = new Workbook();
// 打开 xlsx 文件
workbook.open("Basic sales report1.xlsx", OpenFileFormat.Xlsx);
// 将工作簿另存为 xlsx 文件
workbook.save("Exported.xlsx", SaveFileFormat.Xlsx);以下示例代码展示了如何通过文件流导入和导出 .xlsx 文档:
// 创建一个新的工作簿
var streamworkbook = new Workbook();
// 创建一个新的文件流以打开文件
InputStream openFile;
try {
openFile = new FileInputStream("Basic sales report1.xlsx");
// 打开 xlsx 文件
streamworkbook.open(openFile, OpenFileFormat.Xlsx);
} catch (FileNotFoundException e1) {
// 自动生成的代码块
e1.printStackTrace();
}
// 创建一个新的文件流以保存文件
OutputStream out;
try {
out = new FileOutputStream("Exported-Stream.xlsx");
// 将工作簿另存为 xlsx 文件
streamworkbook.save(out, SaveFileFormat.Xlsx);
} catch (FileNotFoundException e) {
// 自动生成的代码块
e.printStackTrace();
}在另一种常见场景中,你可能只需从电子表格或单元格区域中导入数据。针对这类需求,GcExcel Java 提供了 importData 方法,可高效地从外部工作表或单元格区域加载数据。有关仅导入数据的更多信息,请参见下文的仅导入数据章节。
若要从指定的工作表或单元格区域中仅导入数据,GcExcel Java 提供了 importData 方法,该方法可直接打开工作表并提取数据。当你只需要数据,无需处理工作簿的其他对象模型时,此方法非常实用。
importData 方法的主要参数为文件名/文件流和数据源名称,你可以将工作表、表格或单元格区域的名称指定为数据源。
若要获取文件或文件流中包含的工作表和表格名称,Workbook 类提供了 getNames 方法,该方法会返回一个包含所有可用数据源名称的数组。
// 创建一个新的工作簿
Workbook workbook = new Workbook();
// 打开一个 Excel 文件
InputStream fileStream = getResourceStream("AgingReport.xlsx");
// 获取该文件中所有可用的导入数据源名称
// 数组元素 names[0] 和 names[1] 为工作表名称:"Aging Report"、"Invoices"
// 数组元素 names[2] 和 names[3] 为表格名称:"'Aging Report'!tblAging"、"Invoices!tblInvoices"
String[] names = Workbook.getNames(fileStream);
// Java 平台的 InputStream 无法重复读取,因此需要重新创建一个文件流
InputStream fileStream2 = getResourceStream("AgingReport.xlsx");
// 从文件流中导入表格 "'Aging Report'!tblAging" 的数据
Object[][] data = Workbook.importData(fileStream2, names[2]);
// 将导入的数据赋值给当前工作簿的第一个工作表
workbook.getWorksheets().get(0).getRange(0, 0, data.length, data[0].length).setValue(data);
// 将工作簿另存为 Excel 文件
workbook.save("ImportDataForTable.xlsx");在处理包含多个工作表或大量公式的大型文件时,使用 importData 方法可优化加载性能,因为该方法仅读取数据。该方法还提供了重载版本,允许你指定目标单元格区域,即使文件包含海量数据,也可只读取指定部分的内容。
局限性
使用 importData 方法时,公式不会被计算——因为此场景下计算引擎不会运行,因此单元格值会被设为 null。但如果公式的缓存值已存储在文件中,GcExcel 会返回该缓存值。
如果工作表名称包含字符 !(例如 "Sheet!1"),调用 importData(worksheetName) 方法将无法解析该名称,函数会返回 null。
导出 .xlsx 文件时,你可以通过 XlsxSaveOptions 类的 setIncludeBindingSource 方法,控制是否将绑定的数据源导出到文件中。
以下示例代码展示了如何在导出 .xlsx 文件时排除绑定数据源:
// 创建一个新的工作簿
var workbook = new Workbook();
// 定义一个 JSON 数据源
String dataSource = "{ \"ds\":" +
"[\n" +
" {\"Area\": \"North America\",\"City\": \"Chicago\",\"Category\": \"Consumer Electronics\",\"Name\": \"Bose 785593-0050\",\"Revenue\": 92800},\n" +
" {\"Area\": \"North America\",\"City\": \"New York\",\"Category\": \"Consumer Electronics\",\"Name\": \"Bose 785593-0050\",\"Revenue\": 92800},\n" +
" {\"Area\": \"South America\",\"City\": \"Santiago\",\"Category\": \"Consumer Electronics\",\"Name\": \"Bose 785593-0050\",\"Revenue\": 19550},\n" +
" {\"Area\": \"Europe\",\"City\": \"Berlin\",\"Category\": \"Consumer Electronics\",\"Name\": \"Sony WH-1000XM4\",\"Revenue\": 30000},\n" +
" {\"Area\": \"Asia\",\"City\": \"Tokyo\",\"Category\": \"Consumer Electronics\",\"Name\": \"Sony WH-1000XM4\",\"Revenue\": 45000},\n" +
" {\"Area\": \"North America\",\"City\": \"Los Angeles\",\"Category\": \"Consumer Electronics\",\"Name\": \"Apple AirPods\",\"Revenue\": 60000},\n" +
" {\"Area\": \"Europe\",\"City\": \"Paris\",\"Category\": \"Consumer Electronics\",\"Name\": \"Apple AirPods\",\"Revenue\": 55000},\n" +
" {\"Area\": \"Asia\",\"City\": \"Seoul\",\"Category\": \"Consumer Electronics\",\"Name\": \"Samsung Galaxy Buds\",\"Revenue\": 40000},\n" +
" {\"Area\": \"South America\",\"City\": \"Buenos Aires\",\"Category\": \"Consumer Electronics\",\"Name\": \"Samsung Galaxy Buds\",\"Revenue\": 35000},\n" +
" {\"Area\": \"North America\",\"City\": \"Toronto\",\"Category\": \"Consumer Electronics\",\"Name\": \"Bose 785593-0050\",\"Revenue\": 50000}\n" +
" ]" +
"}";
// 向工作簿中添加一个工作表用于存放数据源
IWorksheet dataSourceSheet = workbook.getWorksheets().add();
dataSourceSheet.setName("DataSource");
// 在该工作表中创建一个表格,数据源范围为 A1:E4
ITable table = dataSourceSheet.getTables().add(dataSourceSheet.getRange("A1:E4"), true);
// 设置表格的绑定路径
table.setBindingPath("ds");
// 为表格的每一列绑定对应的数据源字段
table.getColumns().get(0).setDataField("Area");
table.getColumns().get(1).setDataField("City");
table.getColumns().get(2).setDataField("Category");
table.getColumns().get(3).setDataField("Name");
table.getColumns().get(4).setDataField("Revenue");
// 为工作表设置数据源
dataSourceSheet.setDataSource(new JsonDataSource(dataSource));
// 创建一个用于存放数据透视表的工作表
IWorksheet pivotSheet = workbook.getWorksheets().get(0);
pivotSheet.setName("PivotSheet");
// 基于上述表格创建数据透视缓存
IPivotCache pivotcache = workbook.getPivotCaches().create(table);
// 在 PivotSheet 工作表的 A1 单元格位置创建数据透视表
IPivotTable pivottable = pivotSheet.getPivotTables().add(pivotcache, pivotSheet.getRange("A1"), "pivottable1");
// 配置数据透视表的字段
IPivotField fieldArea = pivottable.getPivotFields().get("Area");
fieldArea.setOrientation(PivotFieldOrientation.RowField);
IPivotField fieldCity = pivottable.getPivotFields().get("City");
fieldCity.setOrientation(PivotFieldOrientation.RowField);
IPivotField fieldName = pivottable.getPivotFields().get("Name");
fieldName.setOrientation(PivotFieldOrientation.ColumnField);
IPivotField fieldRevenue = pivottable.getPivotFields().get("Revenue");
fieldRevenue.setOrientation(PivotFieldOrientation.DataField);
// 自动调整已用区域的列宽
pivotSheet.getUsedRange().autoFit();
// 关闭列总计和行总计
pivottable.setColumnGrand(false);
pivottable.setRowGrand(false);
// 刷新数据透视表
pivottable.refresh();
// 创建保存选项实例
XlsxSaveOptions saveOptions = new XlsxSaveOptions();
// 设置 IncludeBindingSource 为 false,排除绑定数据源的导出
saveOptions.setIncludeBindingSource(false);
// 保存工作簿
workbook.save("IncludeBindingSourceOption.xlsx", saveOptions);注意:
setIncludeBindingSource方法不会在数据绑定改变表格大小后,将表格恢复至原始大小。该方法仅控制是否导出数据源。
导出 .xlsx 文件时,GcExcel 默认启用共享公式功能(与 Microsoft Excel 一致),以此减小文件体积。如果导出的文件需要被不支持共享公式的第三方库使用,你可以将 setExportSharedFormula 方法设为 false 来禁用此功能。请注意,禁用共享公式会增大导出文件的体积。
以下示例代码展示了如何在导出 .xlsx 文件时禁用共享公式:
// 创建一个新的工作簿
Workbook workbook = new Workbook();
IWorksheet Sheet = workbook.getActiveSheet();
// 为 B1:B5 单元格区域设置公式
Sheet.getRange("B1:B5").setFormula("IF(A1>100,SUM(A1:A5)*AVERAGE(A1:A5),MAX(A1:A5)-MIN(A1:A5))");
// 创建保存选项实例
XlsxSaveOptions saveOptions = new XlsxSaveOptions();
// 禁用共享公式
saveOptions.setExportSharedFormula(false);
// 保存工作簿
workbook.save("NoSharedFormula.xlsx", saveOptions);在 Office Open XML(OOXML)格式的 .xlsx 文件中,公式会根据 setExportSharedFormula 的值,以共享或独立的形式存储,具体如下表所示:
启用共享公式
<sheetData>
<row r="1">
<c r="B1">
<f t="shared" si="0" ref="B1:B5">IF(A1>100,SUM(A1:A5)*AVERAGE(A1:A5),MAX(A1:A5)-MIN(A1:A5))</f>
</c>
</row>
<row r="2">
<c r="B2">
<f t="shared" si="0"/>
</c>
</row>
<row r="3">
<c r="B3">
<f t="shared" si="0"/>
</c>
</row>
<row r="4">
<c r="B4">
<f t="shared" si="0"/>
</c>
</row>
<row r="5">
<c r="B5">
<f t="shared" si="0"/>
</c>
</row>
</sheetData>禁用共享公式
<sheetData>
<row r="1">
<c r="B1">
<f>IF(A1>100,SUM(A1:A5)*AVERAGE(A1:A5),MAX(A1:A5)-MIN(A1:A5))</f>
</c>
</row>
<row r="2">
<c r="B2">
<f>IF(A2>100,SUM(A2:A6)*AVERAGE(A2:A6),MAX(A2:A6)-MIN(A2:A6))</f>
</c>
</row>
<row r="3">
<c r="B3">
<f>IF(A3>100,SUM(A3:A7)*AVERAGE(A3:A7),MAX(A3:A7)-MIN(A3:A7))</f>
</c>
</row>
<row r="4">
<c r="B4">
<f>IF(A4>100,SUM(A4:A8)*AVERAGE(A4:A8),MAX(A4:A8)-MIN(A4:A8))</f>
</c>
</row>
<row r="5">
<c r="B5">
<f>IF(A5>100,SUM(A5:A9)*AVERAGE(A5:A9),MAX(A5:A9)-MIN(A5:A9))</f>
</c>
</row>
</sheetData>GcExcel Java 不支持导入 .xls 格式的文件。
GcExcel Java 不支持将 .xlsx 文件导出为 XPS 格式。
GcExcel Java 暂不支持以下功能。如果导入的 .xlsx 文件包含这些功能,再次导出后,这些功能将不会被保留:
导致对象丢失的功能
智能艺术(SmartArt)
3D 模型
墨迹(Ink)
股票/货币/地理数据类型
作为单元格数据类型的复选框
导致对象外观改变的功能
应用了效果的形状
用于假设分析的数据表
可能导致导出文件损坏的功能
地图图表
导致内部数据丢失的功能
添加到数据模型中的数据
通过 XML 导入的数据
导致云集成功能丢失的功能
与表单功能所用的调查问卷的集成
与通过“自动化”选项卡添加的脚本的集成