[]
        
立即试用
(Showing Draft Content)

导入和导出.xlsx文档

导入和导出 .xlsx 文档

GcExcel 支持通过指定的打开选项(如条件格式、合并区域、表格等)导入工作簿。

目录

本节概述 GcExcel Java 处理电子表格文档(.xlsx 文件)的方法。

使用 GcExcel Java 创建并保存工作簿时,会自动将其导出至外部路径或文件夹。将 Excel 文件导入 GcExcel Java(即打开文件)时,既可以加载该电子表格的完整模型,也可以只导入数据。GcExcel Java 提供了 open 方法来打开文件,该方法可搭配多种导入标志使用,这些标志可通过 XlsxOpenOptions 类的 setImportFlags 方法进行配置。

同理,若要将工作簿导出为 .xlsx 文件,可使用 save 方法,并通过 GcExcel 提供的多种保存选项,指定导出内容和需要跳过的内容。具体选项如下表所示:

类名

属性

描述

Import Options

XlsxOpenOptions

DoNotAutoFitAfterOpened

指定在打开Excel文件时是否自动调整行高。

DoNotRecalculateAfterOpened

指定在Excel文件打开后是否重新计算公式值。

ImportFlags

提供各种标志以导入工作表的各个方面。有关更多信息。

DigitalSignatureOnly

指示是否以仅数字签名模式打开工作簿。在仅数字签名模式下,除非调用ISignature.Delete,否则现有签名将被保留。但在此模式下,您只能对现有签名行进行签名、添加不可见签名、移除已签名签名行的数字签名或移除不可见签名。其他更改将被丢弃。修改数字签名后,您需要保存工作簿以提交更改。若要以仅数字签名模式打开工作簿,则为True;否则,使用正常模式。默认值为false。

Password

这个xlsx文件的密码。

OpenOptionsBase

FileFormat

表示工作簿打开时的格式。

Export Options

XlsxSaveOptions

IgnoreFormulas

将GcExcel工作表的公式单元格导出为Excel中的值单元格。

ExcludeUnusedStyles

导出文件时,排除未使用的样式。

ExcludeUnusedNames

导出文件时,排除未使用的名称。

ExcludeEmptyRegionCells

排除空单元格,即位于已使用区域之外、具有样式但不包含数据的单元格。

IsCompactMode

指示是否以紧凑模式保存工作簿。默认值为 false。

Password

这个xlsx文件的密码。

IncludeAutoMergedCells

指示是否包含自动合并的单元格。默认值为 false。

IncludeBindingSource

指示在保存文件时是否包含绑定源。默认值为true。

ExportSharedFormula

指定在保存工作簿时是否导出共享公式。默认值为true。

SaveOptionsBase

FileFormat

表示工作簿的保存格式。

以下示例代码展示了如何通过文件名导入和导出 .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&gt;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&gt;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&gt;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&gt;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&gt;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&gt;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 导入的数据

    • 导致云集成功能丢失的功能

      • 与表单功能所用的调查问卷的集成

      • 与通过“自动化”选项卡添加的脚本的集成