前言

昨天有个小伙伴发了一个老外java编写的小工具给我,功能是转换西班牙邮局快递Coreeos express的单据格式成Amazon格式,他的需求是改一下程序为匹配转换另一个快递公司MRW格式到Amazon格式,然而我堂堂一个Blazor发烧友,怎么可能去反编译人家的java修改呢?必须直接撸一个Blazor的啊.

实现目标

拖放多文件上传, 不落地(无中间保存临时文件)直接内存流转换格式, 直接推送弹出下载文件.

分析需求

原始MRW文件.txt

"Abonado","Depto.","Fecha","N. Envio","N. Lote","Tipo de Cobro","Bultos","Kg.","Imp Reemb.","Referencia","Destinatario","Direccion","C.P.","Poblacion","Pais","Servicio","Retorno Alb.",""
"xxx  SL ","N/A","15/02/2023","0263608650029","02636xxx20230214204409","Pagados","1","1","","403-6273741-3115504","Antonia xxx FERNANDEZ","C/MENDEZ NUÑEZ 222","06420","CASTUERA","ESPAÑA","U19E--Urgente 19 Expedición","SinRetorno",""
"xxx  SL ","N/A","15/02/2023","0263608650028","02636xxx20230214204409","Pagados","1","1","","406-8908494-9500324","Baris xxx","Parque Erreniega Parkea,","31180","CIZUR MAYOR","ESPAÑA","U19E--Urgente 19 Expedición","SinRetorno",""

实体类

来源

  public class MrwTicket{public string Abonado { get; set; }[DisplayName("Depto.")]public string Depto { get; set; }public DateTime Fecha { get; set; }[DisplayName("N. Envio")]public string N_Envio { get; set; }[DisplayName("N. Lote")]public string N_Lote { get; set; }[DisplayName("Tipo de Cobro")]public string TipoDeCobro { get; set; }public string Bultos { get; set; }[DisplayName("Kg.")]public string Kg { get; set; }[DisplayName("Imp Reemb.")]public string ImpReemb { get; set; }public string Referencia { get; set; }public string Destinatario { get; set; }public string Direccion { get; set; }[DisplayName("C.P.")]public string CP { get; set; }public string Poblacion { get; set; }public string Pais { get; set; }public string Servicio { get; set; }[DisplayName("Retorno Alb.")]public string RetornoAlb { get; set; }}

转换目标

    public class AmazonTicket{[DisplayName("order-id")]public string Order_id { get; set; }[DisplayName("order-item-id")]public string Order_item_id { get; set; }[DisplayName("quantity")]public string Quantity { get; set; }[DisplayName("ship-date")]public string Ship_date { get; set; }[DisplayName("carrier-code")]public string Carrier_code { get; set; }[DisplayName("carrier-name")]public string Carrier_name { get; set; }[DisplayName("tracking-number")]public string Tracking_number { get; set; }[DisplayName("ship-method")]public string Ship_method { get; set; }}

建立Blazor页面 Mrw2Amazon.razor

拖放上传可以参考往期文章 https://www.cnblogs.com/densen2014/p/16128246.html

组件UI

@page "/Mrw2Amazon"
@inherits PublicComponentsBase
@namespace AmeBlazor.Components<h4>MRW txt 转 Amazon txt</h4><PageTitle>MRW txt 转 Amazon txt</PageTitle><div @ref="UploadElement" style="padding: 20px; width: 200px; height: 200px; background-color: cornflowerblue; border: 2px dashed #0087F7; border-radius: 5px; "><p>拖放上传文件</p><InputFile OnChange="OnChange" class="form-control" multiple @ref="inputFile" />
</div><pre>
<code>@uploadstatus
</code>
</pre>

拖放上传js文件 wwwroot/drag.js

export function init(wrapper, element, inputFile) {//阻止浏览器默认行为document.addEventListener("dragleave", function (e) {e.preventDefault();}, false);document.addEventListener("drop", function (e) {e.preventDefault();}, false);document.addEventListener("dragenter", function (e) {e.preventDefault();}, false);document.addEventListener("dragover", function (e) {e.preventDefault();}, false); element.addEventListener("drop", function (e) {try {var fileList = e.dataTransfer.files; //获取文件对象//检测是否是拖拽文件到页面的操作if (fileList.length == 0) {return false;}inputFile.files = e.dataTransfer.files;const event = new Event('change', { bubbles: true });inputFile.dispatchEvent(event);}catch (e) {wrapper.invokeMethodAsync('DropAlert', e);}}, false);element.addEventListener('paste', function (e) {inputFile.files = e.clipboardData.files;const event = new Event('change', { bubbles: true });inputFile.dispatchEvent(event);}, false);return {dispose: () => {element.removeEventListener('dragleave', onDragLeave);element.removeEventListener("drop", onDrop);element.removeEventListener('dragenter', onDragHover);element.removeEventListener('dragover', onDragHover);element.removeEventListener('paste', handler);}}
}

下载功能

Pages\_Layout.cshtml < /body >之前添加js代码

    <script>window.downloadFileFromStream = async (fileName, contentStreamReference) => {const arrayBuffer = await contentStreamReference.arrayBuffer();const blob = new Blob([arrayBuffer]);const url = URL.createObjectURL(blob);const anchorElement = document.createElement('a');anchorElement.href = url;anchorElement.download = fileName ?? '';anchorElement.click();anchorElement.remove();URL.revokeObjectURL(url);}</script>

组件代码Mrw2Amazon.razor.cs

先拉个库MiniExcel

<PackageReference Include="MiniExcel" Version="1.*" />

  1. 动态加载 drag.js 文件.(参考往期文章,js隔离 https://www.cnblogs.com/densen2014/p/16027851.html)
  2. 使用拖放读取到 IBrowserFile 文件流
  3. 转换为 MemoryStream 供给 MiniExcel 读取. (PS:不能直接使用 IBrowserFile 的 stream , 当作课后作业自己了解一下.)
  4. MiniExcel 读取格式: var mrwTicket = MiniExcel.Query(fs, excelType: ExcelType.CSV).ToList();
  5. 转换格式
  6. 另存为目标格式csv
  7. 直接弹出目标文件下载到浏览器
  8. 全程不落地
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using MiniExcelLibs;
using MiniExcelLibs.Csv;public partial class Mrw2Amazon : IAsyncDisposable{[Inject]IJSRuntime JS { get; set; }//既然不落地,那就不需要这些了//[Inject] //protected Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostEnvironment { get; set; }protected ElementReference UploadElement { get; set; }protected InputFile? inputFile { get; set; }private DotNetObjectReference<Mrw2Amazon>? wrapper;private IJSObjectReference? module;private IJSObjectReference? dropInstance;//既然不落地,那就不需要这些了//protected string UploadPath = "";protected string? uploadstatus;long maxFileSize = 1024 * 1024 * 15;//既然不落地,那就不需要这些了//protected override void OnAfterRender(bool firstRender)//{//if (!firstRender) return;//UploadPath = Path.Combine(HostEnvironment!.WebRootPath, "uploads", "temp"); //初始化上传路径//if (!Directory.Exists(UploadPath)) Directory.CreateDirectory(UploadPath); //不存在则新建目录//}protected async Task OnChange(InputFileChangeEventArgs e){int i = 0;var selectedFiles = e.GetMultipleFiles(100);foreach (var item in selectedFiles){i++;await OnSubmit(item);uploadstatus += Environment.NewLine + $"[{i}]: " + item.Name;}}protected async Task OnSubmit(IBrowserFile efile){try{if (efile == null) return;if (efile.ContentType != "text/plain"){uploadstatus += Environment.NewLine + $"只接受txt文件.{efile.Name}为{efile.ContentType}";return;}await using var fs = new MemoryStream();using var stream = efile.OpenReadStream(maxFileSize);await stream.CopyToAsync(fs);var mrwTicket = MiniExcel.Query<MrwTicket>(fs, excelType: ExcelType.CSV).ToList();var amazonTicket = new List<AmazonTicket>();foreach (var item2 in mrwTicket){amazonTicket.Add(new AmazonTicket(){Order_id = item2.Referencia,Ship_date = item2.Fecha.ToString("MM-dd-yyyy"),Carrier_code = "MRW",Tracking_number = item2.N_Envio.Remove(5, 1),Ship_method = "Urgente 19",});}var memoryStream = new MemoryStream();memoryStream.SaveAs(amazonTicket, excelType: ExcelType.CSV, configuration: new CsvConfiguration() { Seperator = '\t' });memoryStream.Seek(0, SeekOrigin.Begin);using var streamRef = new DotNetStreamReference(stream: memoryStream);await JS.InvokeVoidAsync("downloadFileFromStream", Path.GetFileNameWithoutExtension(efile.Name) + "_amazon.txt", streamRef);uploadstatus += Environment.NewLine + $"{efile.Name} 转换OK";}catch (Exception e){uploadstatus += Environment.NewLine + $"转换出错 {e.Message}";}StateHasChanged();}protected override async Task OnAfterRenderAsync(bool firstRender){if (!firstRender) return;module = await JS.InvokeAsync<IJSObjectReference>("import", "./drag.js");wrapper = DotNetObjectReference.Create(this);dropInstance = await module.InvokeAsync<IJSObjectReference>("init", wrapper, UploadElement, inputFile!.Element);}[JSInvokable]public void DropAlert(string msg){uploadstatus += Environment.NewLine + $"[!Alert!]: " + msg;StateHasChanged();}async ValueTask IAsyncDisposable.DisposeAsync(){if (dropInstance != null){await dropInstance.InvokeVoidAsync("dispose");await dropInstance.DisposeAsync();}if (wrapper != null){wrapper.Dispose();}if (module != null){await module.DisposeAsync();}}}

运行

可接受多文件拖放同时转换

完整代码来的,直接cv应该可以用了.


关联项目

FreeSql QQ群:4336577

BA & Blazor QQ群:795206915

Maui Blazor 中文社区 QQ群:645660665

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名AlexChow,不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系 。

转载声明

本文来自博客园,作者:周创琳 AlexChow,转载请注明原文链接.

AlexChow

今日头条 | 博客园 | 知乎 | Gitee | GitHub

[一键CV] Blazor 拖放上传文件转换格式并推送到浏览器下载相关推荐

  1. 验证上传文件真实格式

    1 /// <summary> 2 /// 验证上传文件真实格式 3 /// </summary> 4 /// <param name="fileUpload& ...

  2. 如何限制FileUpload上传文件的格式

    这个需求需要用到一个验证控件RequiredFieldValidator 如何限制FileUpload上传文件的格式 前言 1.限制上传文件只能为图片格式 2.限制上传文件只能为压缩包 总结 前言 这 ...

  3. c# 用户帐户临时文件夹_注册帐户,上传文件以供批准,以及查看和下载批准的文件

    c# 用户帐户临时文件夹 在你开始前 在本系列的第一部分中,您将学习基本PHP语法,形式和功能,以及如何通过PHP应用程序连接和使用MySQL或任何其他数据库. 关于本教程 本教程将引导您使用PHP构 ...

  4. antd 中 Upload 上传图片宽高限制以及上传文件的格式限制

    一.上传图片的宽高限制 在组件Upload中有一个beforeUpload的API,是文件上传之前的钩子函数,我们需要在这个API中做限制 beforeUpload: file => {this ...

  5. 上传文件转换html异常,JS 文件互转、10 个 HTML 文件上传技巧、Web 用户体验设计提升指南、奇怪的知识——位掩码 | 思否技术周刊...

    上传文件功能可以说是项目经常出现的需求.从在社交媒体上上传照片到在求职网站上发布简历,文件上传无处不在.在本文中,我们将讨论 HTML文件上传支持的10种用法,希望对你有用. 1. 单文件上传 我们可 ...

  6. vue、微信小程序上传文件(base64格式、一般格式)及vue的表格导入和导出

    一.上传文件 1.vue项目 base64格式 onInputChange(el) {var self = this;let file=el.file;let type=file.type.split ...

  7. ElementUI中el-upload中怎样限制上传文件的格式

    场景 使用el-upload上传文件时限制只能上传指定格式的文件. 比如这里只允许上传apk格式的文件. 注: 博客: https://blog.csdn.net/badao_liumang_qizh ...

  8. 上传文件Base64格式(React)

    记录一下上传文件时将文件数据转为Base64的方法 通过 FileReader对象创建一个实例,然后使用 readAsDataURL方法将数据转为Base64格式 注意: 读取过程是异步的 绑定onl ...

  9. element-ui文件上传修改上传文件的格式

    accept=".txt"    //多个文件类型用逗号隔开 在<el-upload></el-upload>标签里添加上面的代码就可以改上传文件的类型了

最新文章

  1. JavaScript时间日期格式化
  2. 浅谈Linux的内存管理机制
  3. CompletableFuture API用法介绍(一)
  4. 我的2017年前端之路总结
  5. 新加入一个团队,我们应该怎么做?
  6. mysql开启远程访问权限
  7. Android 四大组件学习之Activity六
  8. Raki的读paper小记:XLNet: Generalized Autoregressive Pretraining for Language Understanding
  9. sip协议详解_基于SIP协议的媒体录音规范12个应用场景-SIPREC/RFC6341详解
  10. teambition 还是jira_研发管理工具之 Id 比较(Jira/Teambition/TAPD/禅道)
  11. 计算机管理员权限设置在哪里设置方法,计算机管理员权限在哪里设置 电脑系统如何设置管理员权限...
  12. 美利财务平台架构演进
  13. 外牌年检车辆在上海办理年检
  14. win7系统笔记本配置双屏
  15. 求一个整数的各个位数
  16. Sky光遇云野光之翼在哪获得
  17. [POJ1637]SightseeingTour
  18. Windows窗口API
  19. 证券市场基础知识(一)——证券市场概述
  20. spring集成druid示例

热门文章

  1. SVM 的核函数选择和调参
  2. 企业微信应用程序开发WeChatAPI
  3. 数学の入门到入土 第1天
  4. 2020年终总结-2021新年Flag
  5. 英国政府计划到2050年交通运输将脱碳
  6. mPEG2000-EP,含有环氧基的线性单功能PEG,mPEG2000-Epoxide
  7. 41、Springboot 文件上传 采用Base64方式
  8. 建模厉器E-RWin
  9. 百度贴吧挖坟实时监控 python版
  10. java读写Excel工具类