首页 > 其他分享 >Blazor 拖放上传文件转换格式并推送到浏览器下载

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

时间:2023-02-16 08:56:22浏览次数:67  
标签:set DisplayName string get var Blazor 推送 public 拖放

前言

昨天有个小伙伴发了一个老外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. 直接弹出目标文件下载到浏览器
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应该可以用了.

标签:set,DisplayName,string,get,var,Blazor,推送,public,拖放
From: https://www.cnblogs.com/densen2014/p/17125416.html

相关文章

  • 一封传话聚合推送高级特性API
    一封传话聚合推送高级特性API前言上一次介绍了一封传话的API文档的主要推送API,主要用于实现快速推送到微信、企业微信、钉钉、飞书、邮箱、自定义Webhook。集成该API后仅......
  • 一封传话聚合推送API文档
    前言前面介绍了一封传话聚合推送API的在线测试推送的步骤,可以实现一对一发送消息。需求但是我们希望实现:1.群组订阅功能:例如我和我的好友一起加入通道后,只推送一次我......
  • 一次学俩Vue&Blazor:1.4基础-响应式数据
    一、声明式编程和响应式数据1、声明式编程逻辑层修改视图层元素属性值的方式有两种,一是命令式,先通过getElementById等方法获取元素对象,然后再修改对象的属性;二是声明式......
  • 实现简单的`Blazor`低代码
    本篇博客只实现基本的低代码,比如新增组件,动态修改组件参数创建项目首先创建一个空的BlazorServer,并且命名LowCode.Web实现我们还需要引用一个Blazor组件库,由于作者用Ma......
  • 一封传话一对多推送实现步骤
    前言前面介绍了一封传话聚合推送API的在线测试推送的步骤,可以实现一对一发送消息。但是我们希望实现:1.群组订阅功能:例如我和我的好友一起加入通道后,只推送一次我们两个......
  • 一行代码实现微信消息推送
    一行代码实现微信消息推送介绍通过调用一个简单的接口,将要推送的消息提交后,您将在微信收到推送的消息,简单快捷可以应用的场景设备上下线,量化交易,网站公告,服务器异常信息......
  • 打开MASA Blazor的正确姿势4.2:Flex弹性布局
    MASABlazor预定义了Flex弹性布局的样式,可以直接在class属性中直接使用。 一、复习一下之前提到过的Flex样式(转为MASABlazor样式类):1、在容器(父元素)上使用的样式-6个......
  • 打开MASA Blazor的正确姿势1:目录&MASA Blazor是???
    一、MASABlazor???1、前端技术那么多,为什么选Blazor?嗯?!~未来:Blazor将能够融合服务端渲染、SPA、WebAssembly、跨平台开发的多方优势(BlazorUnited)。目前布局方向太多、想......
  • 打开MASA Blazor的正确姿势2:组件总览
    官网文档按拼音罗列组件,且部分嵌套组件没有在导航栏内列出,不利于浏览查阅。本篇文章的主要目的,主要是对所有组件按大家习惯的方式进行分类,简要介绍组件,并建立跳转官方文档......
  • 打开MASA Blazor的正确姿势3.3:组件样式
    一、关于组件样式的理解1、框架和组件前面我们已经说过,现代前端技术,无论是在框架层面(Blazor、Vue、React等),还是组件层面(Bootstrap、MASABlazor、ElementUI、AntDesign等......