目录
基本实现
- 实现在线预览和编辑Excel的功能,尤其是编辑功能,涉及到更复杂的操作,因为需要在Web端提供类似桌面Excel软件的编辑体验。
- 这通常需要一个强大的前端库来处理表格数据的渲染和编辑,以及后端的支持来保存更改。
后端 - Spring Boot
依赖
xml
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
创建Controller(demo)
java
package com.zjl.controller;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@RestController
public class ExcelController {
private Workbook workbook;
private Sheet sheet;
public ExcelController() throws IOException {
workbook = new XSSFWorkbook(new ClassPathResource("sample.xlsx").getInputStream());
sheet = workbook.getSheetAt(0);
}
@GetMapping("/api/excel/preview")
public List<List<String>> previewExcel() {
List<List<String>> data = new ArrayList<>();
for (Row row : sheet) {
List<String> rowData = new ArrayList<>();
for (Cell cell : row) {
rowData.add(getCellValueAsString(cell));
}
data.add(rowData);
}
return data;
}
@PostMapping("/api/excel/edit")
public ResponseEntity<String> editExcel(@RequestParam("row") int row,
@RequestParam("column") int column,
@RequestParam("value") String value) {
Row r = sheet.getRow(row);
if (r == null) {
r = sheet.createRow(row);
}
Cell c = r.getCell(column);
if (c == null) {
c = r.createCell(column);
}
c.setCellValue(value);
try {
FileOutputStream fileOut = new FileOutputStream("target/sample.xlsx");
workbook.write(fileOut);
fileOut.close();
} catch (IOException e) {
return ResponseEntity.badRequest().body("Error saving changes.");
}
return ResponseEntity.ok("Changes saved successfully.");
}
private String getCellValueAsString(Cell cell) {
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf(cell.getNumericCellValue());
default:
return "";
}
}
}
前端 - Vue 3 + Vuetify
- 为了简化前端的表格编辑,可以使用Vuetify这样的框架,它提供了丰富的UI组件。
- 创建Vue 3项目,使用Vite或Vue CLI创建项目。
安装Vuetify和Axios:
shell
npm install vuetify axios
创建组件
html
<template>
<v-data-table
:headers="headers"
:items="rows"
:items-per-page="10"
item-key="id"
show-expand
single-expand
dense
fixed-header
height="600"
@update:items="onUpdateItems"
>
<template v-slot:item="{ item }">
<tr>
<td v-for="(cell, index) in item" :key="index">
<input type="text" :value="cell" @change="handleCellChange($event, item, index)">
</td>
</tr>
</template>
</v-data-table>
</template>
<script setup>
import axios from 'axios';
const { data, pending } = await useAsyncData('excel-preview', () => {
return axios.get('/api/excel/preview').then(response => response.data);
});
const headers = computed(() => data.value ? data.value[0] : []);
const rows = computed(() => data.value ? data.value.slice(1) : []);
function handleCellChange(event, row, index) {
const newRow = [...rows.value];
newRow[row.index][index] = event.target.value;
updateRows(newRow);
}
function updateRows(rows) {
axios.post('/api/excel/edit', {
row: rows[0].index,
column: 0,
value: rows[0][0]
}).then(response => {
console.log(response.data);
}).catch(error => {
console.error(error);
});
}
</script>
注意事项
- 这个示例中的编辑功能非常基础,仅支持修改单个单元格的值。对于更复杂的编辑需求,如公式计算、图表、样式等,可能需要使用专门的在线表格编辑库,如SheetJS或ag-Grid。
- 编辑功能中,每次只更新一个单元格,实际应用中可能需要批量更新多个单元格,以减少与服务器的交互次数。
- 本示例中,编辑后的Excel文件直接保存到服务器的target目录下,实际应用中应考虑更安全的数据存储方案,如数据库或对象存储服务。
- 考虑到性能和用户体验,对于大型Excel文件,可能需要实现分页加载和异步数据更新机制