前言

昨天有个小伙伴发了一个老外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应该可以用了.

最新文章

  1. 使用PowerShell修改操作系统“环境变量”
  2. 在Unity环境下使用抽象和接口
  3. 浅谈Android样式开发之布局优化
  4. 使用Spring发送带附件的电子邮件(站内和站外传送)
  5. 【C】二级指针探秘 &amp; 星号的两种用法(1.与基本类型结合形成另一种类型,比如与int结合形成int* 2.取值操作)
  6. android 评分条 RatingBar 使用及自定义
  7. Java 画图
  8. UILabel 添加图片
  9. 基于DES算法加密的防撞库密码系统项目总结
  10. js 获取url 参数
  11. 【Android - V】之Toolbar的使用
  12. C#切割指定区域图片操作
  13. redis 源代码分析(一) 内存管理
  14. 关于用exec来执行存储过程中,参数带有引号的解决方法
  15. (Problem 7)10001st prime
  16. Spring 通知和顾问进行增强
  17. 关于sizeof与#pragma pack 以及网络上关于字节对齐的一点感想
  18. 微信小程序swiper制作内容高度不定的tab选项卡
  19. Solidity数组
  20. 让IIS支持10万并发

热门文章

  1. Python图像处理丨5种图像处理特效
  2. Vue3 企业级优雅实战 - 组件库框架 - 7 组件库文档的开发和构建
  3. [排序算法] 归并排序 (C++)
  4. (C++) C++ 中 shared_ptr weak_ptr
  5. 面试官:介绍一下 Redis 三种集群模式
  6. day20 关联查询与多表联查 &amp; 子查询与union联合查询 &amp; 数据库定义语言DDL
  7. JS中BOM与DOM操作
  8. OpenVINO计算机视觉模型加速
  9. Python全栈工程师之从网页搭建入门到Flask全栈项目实战(6) - Flask表单的实现
  10. 13-flask博客项目之restful api详解2-使用