从零开始搭建报表工具(二)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, "服务器异常,处理失败"));
   }
}
相关推荐
小码哥_常5 小时前
Spring Boot 牵手Spring AI,玩转DeepSeek大模型
后端
0xDevNull5 小时前
Java反射机制深度解析:从原理到实战
java·开发语言·后端
华洛5 小时前
我用AI做了一个48秒的真人精品漫剧,不难也不贵
前端·javascript·后端
WZTTMoon6 小时前
Spring Boot 中Servlet、Filter、Listener 四种注册方式全解析
spring boot·后端·servlet
standovon6 小时前
Spring Boot整合Redisson的两种方式
java·spring boot·后端
Cosolar6 小时前
LlamaIndex RAG 本地部署+API服务,快速搭建一个知识库检索助手
后端·openai·ai编程
MX_93597 小时前
SpringMVC请求参数
java·后端·spring·servlet·apache
忆想不到的晖8 小时前
Codex 探索:别急着调 Prompt,先把工作流收住
后端·agent·ai编程
weixin_408099678 小时前
【实战对比】在线 OCR 识别 vs OCR API 接口:从个人工具到系统集成该怎么选?
图像处理·人工智能·后端·ocr·api·图片文字识别·文字识别ocr
Victor3569 小时前
MongoDB(73)如何设置用户权限?
后端