Blazor 拖放上传文件转换格式并推送到浏览器下载

前言

昨天有个小伙伴发了一个老外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","" 

Blazor 拖放上传文件转换格式并推送到浏览器下载

Blazor 拖放上传文件转换格式并推送到浏览器下载

实体类

来源

  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. 直接弹出目标文件下载到浏览器
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();             }         }      }  

运行

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

Blazor 拖放上传文件转换格式并推送到浏览器下载

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

发表评论

相关文章