电子表格编辑器 与文件一起使用
目录
- 支持的文件
- 打开本地文件
- LoaderService.buildColumnWidthCache
- LoaderService.buildRowHeightCache
- 从 Dropbox 打开
- 从URL打开
- LoaderService.fromUrl
- LoaderService.buildCellsCache
- LoaderService.buildColumnWidthCache
- LoaderService.buildRowHeightCache
- 创建新电子表格
- LoaderService.fromBlank
- buildCellsCache
- buildColumnWidthCache
- buildRowHeightCache
- 导出到各种格式
支持的文件
HTML5 电子表格编辑器可以打开以下格式的文件:
- Excel 1997-2003 XLS
- Excel 2007-2013 XLSX
- XLSM
- XLSB
- XLTX
- SpreadsheetML
- CVS
- OpenDocument
打开本地文件
上传来自本地计算机的文件:
- 切换到顶部的 文件 选项卡。
- 单击从计算机打开以打开浏览对话框.
- 转到所需的文件位置。
- 点击所需的文件以选择它。
- 点击 打开。
文件将在编辑器中打开。
它是如何工作的?
文件上传
用户从本地计算机中选择一个文件,该文件通过 Web 浏览器上传到服务器,并由 PrimeFaces fileUpload 组件接收。
<p:fileUpload fileUploadListener="#\{workbook.onFileUpload\}" update=":ribbon :intro :sheet" />
管理工作簿
一旦文件完全上传,WorkbookService.onFileUpload 方法开始处理情况。WorkbookService 从 Web 浏览器接收事件,并跟踪整个工作簿的状态。WorkbookService.onFileUpload 将控制权转交给 LoaderService 将工作簿加载到内存中。由于 fileUpload 组件将已上传的文件提供为 InputStream,LoaderService 使用 LoaderService.fromInputStream 方法进行加载。
public void onFileUpload(FileUploadEvent e) {
this.current = loader.fromInputStream(e.getFile().getInputstream(), e.getFile().getFileName());
}
加载和卸载
LoaderService.fromInputStream 方法读取 component 提供的 InputStream,创建 com.aspose.cells.Workbook 类的实例。只要用户在 Web 浏览器中查看或编辑电子表格,这个实例就会保留在内存中。当用户离开编辑器或关闭浏览器时,未使用的实例会自动从内存中卸载,以保持服务器的整洁。
public String fromInputStream(InputStream s, String name) {
com.aspose.cells.Workbook w;
try (InputStream i = s) {
w = new com.aspose.cells.Workbook(i);
} catch (Exception x) {
return null;
}
String key = this.generateKey();
this.workbooks.put(key, w);
this.buildCellsCache(key);
this.buildColumnWidthCache(key);
this.buildRowHeightCache(key);
return key;
}
缓存
缓存对 HTML5 电子表格编辑器非常重要。它使一切运行顺畅。CellsService 保持缓存行、列、单元格和编辑器加载的所有工作簿的属性。当 LoaderService 完全加载电子表格时,它从上到下读取它,并通过调用 LoaderService.buildCellsCache、LoaderService.buildColumnWidthCache、LoaderService.buildRowHeightCache 填充缓存。
public void buildCellsCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
int maxColumn = ws.getCells().getMaxColumn() + 1;
maxColumn = maxColumn + 26 - (maxColumn % 26);
int maxRow = 20 + ws.getCells().getMaxRow() + 1;
maxRow = maxRow + 10 - (maxRow % 10);
ArrayList<Column> columns = new ArrayList<>(maxColumn);
ArrayList<Row> rows = new ArrayList<>(maxRow);
for (int i = 0; i < maxColumn; i++) {
columns.add(i, new Column(i, com.aspose.cells.CellsHelper.columnIndexToName(i)));
}
for (int i = 0; i < maxRow; i++) {
rows.add(i, new Row.Builder().setId(i).build());
}
for (Object o : ws.getCells()) {
com.aspose.cells.Cell c = (com.aspose.cells.Cell) o;
rows.get(c.getRow()).putCell(c.getColumn(), cells.fromAsposeCell(c));
}
for (int i = 0; i < maxRow; i++) {
for (int j = 0; j < maxColumn; j++) {
String col = com.aspose.cells.CellsHelper.columnIndexToName(j);
if (!rows.get(i).getCellsMap().containsKey(col)) {
rows.get(i).putCell(col, cells.fromBlank(j, i));
}
}
}
cells.putColumns(key, columns);
cells.putRows(key, rows);
}
LoaderService.buildColumnWidthCache
public void buildColumnWidthCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
ArrayList<Integer> columnWidth = new ArrayList<>();
for (int i = 0; i < cells.getColumns(key).size(); i++) {
columnWidth.add(i, ws.getCells().getColumnWidthPixel(i));
}
cells.putColumnWidth(key, columnWidth);
}
LoaderService.buildRowHeightCache
public void buildRowHeightCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
ArrayList<Integer> rowHeight = new ArrayList<>();
for (int i = 0; i < cells.getRows(key).size(); i++) {
rowHeight.add(i, ws.getCells().getRowHeightPixel(i));
}
cells.putRowHeight(key, rowHeight);
}
从 Dropbox 打开
要从 Dropbox 打开文件:
- 切换到顶部的 文件 选项卡。
- 点击 从 Dropbox 打开 打开 Dropbox 文件选择器。
- 如果您尚未登录,它将要求您登录到您的 Dropbox 帐户。
- 导航到所需的文件并单击选择。
- 在底部单击选择。
您选择的文件将从Dropbox中打开。
它是如何工作的?
从Dropbox打开按钮使用Dropbox JavaScript选择器API来打开Dropbox选择器对话框。选择器提供所选文件的URL,由回调函数捕获并发送回服务器。服务器从URL创建电子表格的实例,初始化一些日常事务处理工作,并将DOM更新发送回浏览器。浏览器渲染并刷新HTML,用户准备编辑加载的文档。
从URL打开
文件可以直接从URL打开。这允许用户编辑互联网上的任何公开可用的文件。在加载编辑器时,添加**?url=位置**参数,并将您所需的**位置**的值附加到文件末尾。例如:
http://editor.aspose.com/?url=http://example.com/Sample.xlsx
它是如何工作的?
在启动期间实例化
当WorksheetView后端bean由JSF实例化时,将调用PostConstruct方法init,使用LoaderService.fromUrl加载电子表格。
缓存
电子表格加载完毕后立即进行缓存。LoaderService 依次调用 LoaderService.buildCellsCache、LoaderService.buildColumnWidthCache 和 LoaderService.buildRowHeightCache 进行电子表格内容的缓存,以确保所有操作快速流畅。
DOM 更新
服务器端准备好电子表格后,使用 JSF 组件生成新的 HTML,并向用户发送 DOM 更新,由 Web 浏览器进行渲染。
@PostConstruct
private void init() {
String requestedSourceUrl = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("url");
if (requestedSourceUrl != null) {
try {
this.sourceUrl = new URL(requestedSourceUrl).toString();
this.loadFromUrl();
} catch (MalformedURLException x) {
msg.sendMessageDialog("The specified URL is invalid", requestedSourceUrl);
}
}
}
LoaderService.fromUrl
public String fromUrl(String url) {
com.aspose.cells.Workbook w;
try (InputStream i = new URL(url).openStream()) {
w = new com.aspose.cells.Workbook(i);
} catch (Exception x) {
throw new RuntimeException(x);
}
String key = generateKey();
workbooks.put(key, w);
buildCellsCache(key);
buildColumnWidthCache(key);
buildRowHeightCache(key);
return key;
}
LoaderService.buildCellsCache
public void buildCellsCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
int maxColumn = ws.getCells().getMaxColumn() + 1;
maxColumn = maxColumn + 26 - (maxColumn % 26);
int maxRow = 20 + ws.getCells().getMaxRow() + 1;
maxRow = maxRow + 10 - (maxRow % 10);
ArrayList<Column> columns = new ArrayList<>(maxColumn);
ArrayList<Row> rows = new ArrayList<>(maxRow);
for (int i = 0; i < maxColumn; i++) {
columns.add(i, new Column(i, com.aspose.cells.CellsHelper.columnIndexToName(i)));
}
for (int i = 0; i < maxRow; i++) {
rows.add(i, new Row.Builder().setId(i).build());
}
for (Object o : ws.getCells()) {
com.aspose.cells.Cell c = (com.aspose.cells.Cell) o;
rows.get(c.getRow()).putCell(c.getColumn(), cells.fromAsposeCell(c));
}
for (int i = 0; i < maxRow; i++) {
for (int j = 0; j < maxColumn; j++) {
String col = com.aspose.cells.CellsHelper.columnIndexToName(j);
if (!rows.get(i).getCellsMap().containsKey(col)) {
rows.get(i).putCell(col, cells.fromBlank(j, i));
}
}
}
cells.putColumns(key, columns);
cells.putRows(key, rows);
}
LoaderService.buildColumnWidthCache
public void buildColumnWidthCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
ArrayList<Integer> columnWidth = new ArrayList<>();
for (int i = 0; i < cells.getColumns(key).size(); i++) {
columnWidth.add(i, ws.getCells().getColumnWidthPixel(i));
}
cells.putColumnWidth(key, columnWidth);
}
LoaderService.buildRowHeightCache
public void buildRowHeightCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
ArrayList<Integer> rowHeight = new ArrayList<>();
for (int i = 0; i < cells.getRows(key).size(); i++) {
rowHeight.add(i, ws.getCells().getRowHeightPixel(i));
}
cells.putRowHeight(key, rowHeight);
}
创建新电子表格
要创建一个新的空白电子表格:
- 切换到 文件 选项卡。
- 点击 新建 按钮。
如果有打开的电子表格文件,编辑器将关闭该文件并打开一个新的文件。
它是如何工作的?
实例化一个新对象
当用户点击 新建 按钮时,将调用 WorksheetView.loadBlank,最终调用 LoaderService.fromBlank。 LoaderService 会创建一个新的空白电子表格实例。
缓存
电子表格加载完毕后立即进行缓存。LoaderService 依次调用 LoaderService.buildCellsCache、LoaderService.buildColumnWidthCache 和 LoaderService.buildRowHeightCache 进行电子表格内容的缓存,以确保所有操作快速流畅。
DOM 更新
服务器端准备好电子表格后,使用 JSF 组件生成新的 HTML,并向用户发送 DOM 更新,由 Web 浏览器进行渲染。
public void loadBlank() {
this.loadedWorkbook = loader.fromBlank();
}
LoaderService.fromBlank
public String fromBlank() {
com.aspose.cells.Workbook w = new com.aspose.cells.Workbook();
String key = generateKey();
workbooks.put(key, w);
buildCellsCache(key);
buildColumnWidthCache(key);
buildRowHeightCache(key);
return key;
}
buildCellsCache
public void buildCellsCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
int maxColumn = ws.getCells().getMaxColumn() + 1;
maxColumn = maxColumn + 26 - (maxColumn % 26);
int maxRow = 20 + ws.getCells().getMaxRow() + 1;
maxRow = maxRow + 10 - (maxRow % 10);
ArrayList<Column> columns = new ArrayList<>(maxColumn);
ArrayList<Row> rows = new ArrayList<>(maxRow);
for (int i = 0; i < maxColumn; i++) {
columns.add(i, new Column(i, com.aspose.cells.CellsHelper.columnIndexToName(i)));
}
for (int i = 0; i < maxRow; i++) {
rows.add(i, new Row.Builder().setId(i).build());
}
for (Object o : ws.getCells()) {
com.aspose.cells.Cell c = (com.aspose.cells.Cell) o;
rows.get(c.getRow()).putCell(c.getColumn(), cells.fromAsposeCell(c));
}
for (int i = 0; i < maxRow; i++) {
for (int j = 0; j < maxColumn; j++) {
String col = com.aspose.cells.CellsHelper.columnIndexToName(j);
if (!rows.get(i).getCellsMap().containsKey(col)) {
rows.get(i).putCell(col, cells.fromBlank(j, i));
}
}
}
cells.putColumns(key, columns);
cells.putRows(key, rows);
}
buildColumnWidthCache
public void buildColumnWidthCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
ArrayList<Integer> columnWidth = new ArrayList<>();
for (int i = 0; i < cells.getColumns(key).size(); i++) {
columnWidth.add(i, ws.getCells().getColumnWidthPixel(i));
}
cells.putColumnWidth(key, columnWidth);
}
buildRowHeightCache
public void buildRowHeightCache(String key) {
com.aspose.cells.Workbook wb = workbooks.get(key);
com.aspose.cells.Worksheet ws = wb.getWorksheets().get(wb.getWorksheets().getActiveSheetIndex());
ArrayList<Integer> rowHeight = new ArrayList<>();
for (int i = 0; i < cells.getRows(key).size(); i++) {
rowHeight.add(i, ws.getCells().getRowHeightPixel(i));
}
cells.putRowHeight(key, rowHeight);
}
导出到各种格式
编辑文件后,用户希望保存更改。编辑器允许用户将修改后的电子表格导出并下载到本地计算机。要导出文件:
- 切换到顶部的 文件 选项卡。
- 点击 导出 按钮。
- 从下拉菜单中选择所需的格式。
修改后的文件将被导出并可下载。支持以下格式进行导出:
- Excel 2007-2013 XLSX
- Excel 1997-2003 XLS
- Excel XLSM
- Excel XLSB
- Excel XLTX
- Excel XLTM
- SpreadsheetML
- 便携式文档格式 (PDF)
- 开放文档表格 (ODS)
它是如何工作的?
打开的电子表格将使用 WorksheetView.getOutputFile 转换为用户指定的格式。
public StreamedContent getOutputFile(int saveFormat) {
byte[] buf;
String ext = null;
switch (saveFormat) {
case com.aspose.cells.SaveFormat.EXCEL_97_TO_2003:
ext = "xls";
break;
case com.aspose.cells.SaveFormat.XLSX:
ext = "xlsx";
break;
case com.aspose.cells.SaveFormat.XLSM:
ext = "xlsm";
break;
case com.aspose.cells.SaveFormat.XLSB:
ext = "xlsb";
break;
case com.aspose.cells.SaveFormat.XLTX:
ext = "xltx";
break;
case com.aspose.cells.SaveFormat.XLTM:
ext = "xltm";
break;
case com.aspose.cells.SaveFormat.SPREADSHEET_ML:
ext = "xml";
break;
case com.aspose.cells.SaveFormat.PDF:
ext = "pdf";
break;
case com.aspose.cells.SaveFormat.ODS:
ext = "ods";
break;
}
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
getAsposeWorkbook().save(out, saveFormat);
buf = out.toByteArray();
} catch (Exception x) {
throw new RuntimeException(x);
}
return new DefaultStreamedContent(new ByteArrayInputStream(buf), "application/octet-stream", "Spreadsheet." + ext);
}