上传功能
代码一
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body> <!-- action 使用 axios 上传,#号 limit 只允许上传一个文件 accept 限制格式 on-progress 上传中回调方法,做上传禁用的功能 disabled 禁用开关 auto-upload 禁止自动上传 on-change 上传后的处理 --> <el-upload action="#" :limit="1" accept=".xlsx, .xls" :on-progress="handleFileProgress" :disabled="upload.isUploading" :auto-upload="false" drag :on-change="handleChangeUpload"> <!--icon 标签--> <el-icon class="el-icon--upload"> <UploadFilled/> </el-icon> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> <template #tip> <div class="el-upload__tip text-center"> <span>仅允许导入xls、xlsx格式文件。</span> <!--下载模版--> <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate"> 下载模板 </el-link> </div> </template> </el-upload> <template #footer> <div class="dialog-footer"> <!--确定后下载--> <el-button type="primary" @click="submitFileForm">确 定</el-button> <el-button @click="upload.open = false">取 消</el-button> </div> </template> </el-dialog>
代码二
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body> <el-upload :action="upload.url" ref="uploadRef" :limit="1" accept=".xlsx, .xls" :on-progress="handleFileProgress" :disabled="upload.isUploading" :auto-upload="false" drag :headers="upload.headers" :on-success="handleFileSuccess"> <el-icon class="el-icon--upload"> <UploadFilled/> </el-icon> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> <template #tip> <div class="el-upload__tip text-center"> <span>仅允许导入xlsx格式文件。</span> <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate"> 下载模板 </el-link> </div> </template> </el-upload> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitFileForm">确 定</el-button> <el-button @click="upload.open = false">取 消</el-button> </div> </template> </el-dialog>
/*** 用户导入参数 */ const upload = ref({ open: false, title: '设备导入', // 是否禁用上传 isUploading: false, headers: { Authorization: 'Bearer ' + getToken() }, url: import.meta.env.VITE_APP_BASE_API + '/ar_check/device/importData' }) // 打开导入 function handleTeamImport() { upload.value.open = true } // 文件上传中 function handleFileProgress() { upload.value.isUploading = true } // 文件上传完成 function handleFileSuccess(response, file) { upload.value.open = false upload.value.isUploading = false proxy.$refs['uploadRef'].handleRemove(file) proxy.$alert('<div style=\'overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>' + response.msg + '</div>', '导入结果', { dangerouslyUseHTMLString: true }) getList() } // 下载模板 function importTemplate() { proxy.download('ar_check/device/importTemplate', {}, `device_template_${new Date().getTime()}.xlsx`) } // 确定上传 async function submitFileForm() { proxy.$refs.uploadRef.submit() }
介绍一下 POI OOXML 的使用
首先需要创建一个工作薄,这里有几个注意事项
- HSSF - 提供读写Microsoft Excel XLS格式档案的功能。
- XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。
- HWPF - 提供读写Microsoft Word DOC97格式档案的功能。
- XWPF - 提供读写Microsoft Word DOC2003格式档案的功能。
- HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
- HDGF - 提供读Microsoft Visio格式档案的功能。
- HPBF - 提供读Microsoft Publisher格式档案的功能。
- HSMF - 提供读Microsoft Outlook格式档案的功能。
在工作页创建行以及单元格。
// 新建一个工作簿 Workbook workbook = new XSSFWorkbook(); // 创建sheet页 Sheet sheet = workbook.createSheet(); // 在第三行开始写 Row row = sheet.createRow(3); Cell cell = row.createCell(0); cell.setCellValue("哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"); // 合并行,表示表的第三列,结束第三列,合并 0 - 6 行 sheet.addMergedRegion(new CellRangeAddress(3, 3, 0, 8)); // 创建单元格样式 CellStyle cellStyle = workbook.createCellStyle(); // 设置单元格居中方式---左对齐 cellStyle.setAlignment(HorizontalAlignment.LEFT); // 应用单元格样式 cell.setCellStyle(cellStyle); // 将数据写入到文件中 FileOutputStream fout = new FileOutputStream("D:\\Downloads\\example.xlsx"); workbook.write(fout); fout.close(); workbook.close();
设置单元格格式以及字体样式
// 创建单元格样式 CellStyle cellStyle2 = workbook.createCellStyle(); // 设置单元格居中方式---居中 cellStyle2.setAlignment(HorizontalAlignment.CENTER); // 设置单元格颜色--灰色 cellStyle2.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); // 使用单一颜色填充 cellStyle2.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 字体格式 Font font = workbook.createFont(); // 加粗 font.setBold(true); // 设置颜色--白色 font.setColor(IndexedColors.WHITE.getIndex()); // 将字体设置到样式上 cellStyle2.setFont(font); // 最后单元格使用样式 t1.setCellStyle(cellStyle2);
最后输出到指定位置
// 创建一个文件输出流,用于将工作簿写入文件 FileOutputStream fout = new FileOutputStream("D:\\Downloads\\example.xlsx"); // 将工作簿写入文件流 workbook.write(fout); // 关闭文件流 fout.close(); // 关闭工作簿 workbook.close();
获取 excel 的图片
图片是独立的,根据单元格的位置获取
InputStream inputStream = Files.newInputStream(Paths.get("D:\\Downloads\\device_template_1714287622392.xlsx")); XSSFWorkbook workbook = new XSSFWorkbook(inputStream); // 获取第一个 sheet 表 XSSFSheet sheet = workbook.getSheetAt(0); if (sheet == null) { throw new IOException("损坏的文件!"); } // 获取绘图包 XSSFDrawing drawing = sheet.getDrawingPatriarch(); if (drawing != null) { // 获取所有图形形状 List<XSSFShape> shapes = drawing.getShapes(); for (XSSFShape shape : shapes) { // 形状获取对应的图片数据 XSSFPicture picture = (XSSFPicture) shape; XSSFPictureData pictureData = picture.getPictureData(); //图片形状在工作表中的位置, 所在行列起点和终点位置 XSSFClientAnchor anchor = (XSSFClientAnchor) shape.getAnchor(); // 行 short col1 = anchor.getCol1(); // 列 int row1 = anchor.getRow1(); //文件扩展名 String suffix = pictureData.suggestFileExtension(); // 文件格式 String mimeType = pictureData.getMimeType(); // 文件数据 byte[] data = pictureData.getData(); // 转换成 MultipartFile 进行文件上传,参数一和参数二是文件名,参数三是类型,参数四是字节数据 MultipartFile multipartFile = new MockMultipartFile("", "", mimeType, data); } }
下载模板功能实现
首先后端完成上面的excel 文件格式内容等
前端调用 SpringMvc 接口
import { saveAs } from 'file-saver' try { const downloadLoadingInstance = ElLoading.service({ text: '正在下载数据,请稍候', background: 'rgba(0, 0, 0, 0.7)' }) // 发送 POST 请求到指定的 URL,获取响应数据 const data = await service.post(url, {}, { // 设置请求头为 'application/x-www-form-urlencoded' headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, // 设置响应类型为 Blob responseType: 'blob' }) // 如果响应数据存在 if (data) { // 检查响应数据是否为 Blob 类型---是否是JSON const isBlob = blobValidate(data) if (isBlob) { // 如果是 Blob 类型,则创建 Blob 对象并保存为文件 const blob = new Blob([data]) saveAs(blob, filename) } } // 关闭加载动画 downloadLoadingInstance.close() } catch (error) { console.error(error) // 显示下载文件错误信息 ElMessage.error('下载文件出现错误,请联系管理员!') // 关闭加载动画 downloadLoadingInstance.close() }
上传导入
需要创建一个输入流来读取 execel 文件。
getLastRowNum 获取有文本内容的最后一行列的索引,因为我这里前五行是解释内容,所以 == 5 表示没有数据。
如果是前端传递的,要这样写 MultipartFile 的 getInputStream 方法获取流
InputStream inputStream = Files.newInputStream(Paths.get("D:\\Downloads\\team_template_1714287622392.xlsx")); Workbook workbook = WorkbookFactory.create(inputStream); // 获取第一个 sheet 表 Sheet sheet = workbook.getSheetAt(0); if (sheet == null) { throw new IOException("损坏的文件!"); } if (sheet.getLastRowNum() == 5) { throw new IOException("导入班组数据不能为空!"); }
由于 poi ooxml 读取数据需要指定类型很麻烦,我做了一个方法转换
/** * 将单元格的值以字符串形式返回。 * * @param cell 单元格对象 * @return 字符串形式的单元格值,如果单元格为 null,则返回空字符串 */ public static String getCellValueAsString(Cell cell) { if (cell == null) { return ""; } switch (cell.getCellType()) { case NUMERIC: // 如果单元格类型为数字,将数字转换为字符串并去除空格 return String.valueOf((long) cell.getNumericCellValue()).trim(); case BOOLEAN: // 如果单元格类型为布尔值,将布尔值转换为字符串并去除空格 return String.valueOf(cell.getBooleanCellValue()).trim(); case STRING: // 如果单元格类型为字符串,直接返回字符串并去除空格 return cell.getStringCellValue().trim(); case FORMULA: // 如果单元格是公式,将计算结果作为字符串返回,并去除空格 return cell.getCellFormula().trim(); case BLANK: // 如果单元格为空,返回空字符串 return ""; case ERROR: // 如果单元格是错误类型,返回错误码作为字符串 return String.valueOf(cell.getErrorCellValue()); default: // 其他类型的单元格返回空字符串 return ""; } }
以上就是浅析Vue3中Excel下载模板并导入数据功能的实现的详细内容,更多关于Vue3 Excel下载模板并导入数据的资料请关注其它相关文章!