从零开始搭建报表工具(二)EXCEL导入数据

前言

本篇文章是从零开始搭建报表工具系列文章的第二篇,实现在第一篇的在线填报基础上进行优化,可使用原始模板Excel上录入数据,直接Excel导入进系统使用。

可能适用的场景

  1. 表格数据中存在公式计算,可以在原始模板中使用微软表格自带的公式。
  2. 习惯使用Excel的用户,微软表格功能强大,而我们的在线表格功能单一

实现原理

graph LR 导入表格 --> 识别内容 识别内容 --> 放到制作的模板相同位置 放到制作的模板相同位置 --> 在线渲染 在线渲染-->采集数据 采集数据 --> 保存到数据库

使用流程图

graph LR 开始 --> 下载模板 下载模板 --> 添加数据 添加数据 --> 上传Excel 上传Excel --> 在线预览或修改数据 在线预览或修改数据--> 开始生成

体验网址

体验网址:http://121.41.170.62/login

项目还在一点点完善中,仅供学习参考!可能无法访问。

实现步骤

当前Excel数据源仅支持静态表格,如果你的数据源是列表方式,请查看后续文章动态表单部分。

静态表格:不存在任何新增行或插入列的表格,所有的位置都是固定不变的。

这里继续以授权委托书.xlsx为例

STEP-1 下载

原始模板即上传时的模板,如果你本地已经存在可以不用再次下载。

进入上传填报\选择模板,这里选择授权委托书,选中后页面刷新后点击开始下载

STEP-2 表格中填充数据

表格中可以使用任何公式,但要保证位置不会发生变化。

STEP-3 EXCEL上传

点击第二步-开始上传,选择携带数据的Excel表格,点击提交上传

STEP-4 预览并修改数据

点击第三步-预览数据,可修改数据。

STEP-5 提交数据并生成

点击第四步-开始生成开始生成,等待成功。

最终转化文档样式

关键源码(C#部分)

使用NPOI读取Excel文件内容。

csharp 复制代码
/// <summary>
/// 处理Excel上传 并转换成HTML
/// </summary>
/// <returns></returns>
[Authorize]
[HttpPost("/api/xxx/processExcelUpload")]
public async Task<IActionResult> ProcessExcelUpload([FromForm] ExcelUploadInput inputData)
{
   // 获取用户ID
   var authorId = User.FindFirstValue("Id");

   // 获取上传的文件
   var uploadedFile = inputData.UploadedFile;

   //验证文件大小,限制为100KB
   const int maxAllowedFileSize = 1024 * 100; //100KB
   if (uploadedFile.Length > maxAllowedFileSize)
   {
       return BadRequest("文件大小超过限制100KB.");
   }
   
   // 验证文件类型,仅支持xlsx格式
   var permittedFileTypes = new[] { "xlsx" };
   var fileExtension = Path.GetExtension(uploadedFile.FileName).TrimStart('.').ToLowerInvariant();
   if (!permittedFileTypes.Contains(fileExtension))
   {
       return BadRequest("文件格式不支持,仅支持xlsx格式.");
   }
   
   // 这里省略了危险文件过滤操作
   
   try
   {
       // 设置基础存储路径
       var baseStoragePath = "uploads";

       //生成随机文件名
       var randomFileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
       var newFileName = $"{randomFileNameWithoutExtension}.{fileExtension}";

       // 定义文件的存储路径
       var currentDateString = DateTime.Now.ToString("yyyy-MM-dd");
       var targetDirectoryPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", baseStoragePath, currentDateString, authorId, "data");
       var targetFilePath = Path.Combine(targetDirectoryPath, newFileName);

       // 如果目标路径不存在, 则创建目标路径
       Directory.CreateDirectory(targetDirectoryPath); 

       // 初始化文件流并将上传的文件保存到目标路径
       using (var fileStream = new FileStream(targetFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
       {
           await uploadedFile.CopyToAsync(fileStream);
           fileStream.Close();
       }

       // 将Excel转换为HTML ConvertExcelToHtml()在第一章中
       var conversionResult = NpoiHelper.ConvertExcelToHtml(targetFilePath);

       return Json(conversionResult);
   }
   catch (Exception ex)
   {
       return Json(SetResult(500, ex.Message, "服务器异常,处理失败"));
   }
}
相关推荐
monkey_meng23 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马26 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng29 分钟前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
paopaokaka_luck5 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
码农小旋风6 小时前
详解K8S--声明式API
后端
Peter_chq6 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml47 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~7 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616887 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
睡觉谁叫~~~8 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust