Basic Vue upload page that reads excel file. No document validation. ASP.Net API with endpoint to request the current data standard and an endpoint to allow for excel uploads.
parent
b0d5c04d9c
commit
e74ebcea6a
@ -0,0 +1,20 @@ |
||||
namespace backend.Models |
||||
{ |
||||
|
||||
public class ColumnStandard |
||||
{ |
||||
public ColumnStandard(string header, string headerRegex, string valueRegex, bool nullable = false) |
||||
{ |
||||
Header = header; |
||||
HeaderRegex = headerRegex; |
||||
ValueRegex = valueRegex; |
||||
Nullable = nullable; |
||||
} |
||||
public string Header { get; set; } |
||||
public string HeaderRegex { get; set; } |
||||
public string ValueRegex { get; set; } |
||||
public bool Nullable { get; set; } |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,43 @@ |
||||
|
||||
using Microsoft.AspNetCore.Mvc; |
||||
|
||||
namespace backend.Controllers |
||||
{ |
||||
[Route("api/excelupload")] |
||||
[ApiController] |
||||
public class ExcelUpload : ControllerBase |
||||
{ |
||||
private readonly IConfiguration _config; |
||||
|
||||
|
||||
public ExcelUpload(IConfiguration config) |
||||
{ |
||||
_config = config; |
||||
} |
||||
|
||||
[HttpPost] |
||||
public void ProcessUpload(IFormFile file) |
||||
{ |
||||
// TODO : Add some header validation to make sure it comes from a real user |
||||
if (file == null) |
||||
{ |
||||
Console.WriteLine("fail: FILE IS NULL"); |
||||
return; |
||||
} |
||||
|
||||
string dataFileName = Path.GetFileName(file.FileName); |
||||
|
||||
string curDate = DateTime.Now.ToString("u"); |
||||
|
||||
string saveToPath = Path.Combine(_config.GetValue<string>("UploadSavePath"), curDate + '_' + dataFileName); |
||||
|
||||
using (FileStream stream = new FileStream(saveToPath, FileMode.Create)) |
||||
{ |
||||
file.CopyTo(stream); |
||||
Console.WriteLine($"Saved to {saveToPath}."); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,33 @@ |
||||
using Microsoft.AspNetCore.Mvc; |
||||
using backend.Models; |
||||
using Newtonsoft.Json; |
||||
|
||||
namespace backend.Controllers |
||||
{ |
||||
[Route("api/template")] |
||||
[ApiController] |
||||
public class TemplateConfigController : ControllerBase |
||||
{ |
||||
|
||||
private readonly IConfiguration _config; |
||||
|
||||
public TemplateConfigController(IConfiguration configuration) |
||||
{ |
||||
_config = configuration; |
||||
} |
||||
|
||||
[HttpGet] |
||||
public ActionResult<string> Get() |
||||
{ |
||||
Console.WriteLine("template get triggered"); |
||||
List<ColumnStandard>? dataStandard = _config.GetSection("DataStandard").Get<List<ColumnStandard>>(); |
||||
|
||||
if (dataStandard == null) |
||||
{ |
||||
return "Failed to retreieve data standard!"; |
||||
} |
||||
return JsonConvert.SerializeObject(dataStandard); |
||||
} |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,16 @@ |
||||
var builder = WebApplication.CreateBuilder(args); |
||||
|
||||
// Add services to the container. |
||||
builder.Services.AddControllers() |
||||
.AddNewtonsoftJson(); |
||||
|
||||
|
||||
var app = builder.Build(); |
||||
|
||||
app.UseHttpsRedirection(); |
||||
|
||||
app.UseAuthorization(); |
||||
|
||||
app.MapControllers(); |
||||
|
||||
app.Run(); |
||||
@ -0,0 +1,37 @@ |
||||
{ |
||||
"Logging": { |
||||
"LogLevel": { |
||||
"Default": "Information", |
||||
"Microsoft.AspNetCore": "Warning" |
||||
} |
||||
}, |
||||
"AllowedHosts": "*", |
||||
"Test" : "It Worked!", |
||||
"UploadSavePath": "../Uploaded/", |
||||
"DataStandard" : [ |
||||
{"Header": "Contract Number", "HeaderRegex": "PG1 FICO", "ValueRegex": "^\\d+\\d$", "Nullable": false}, |
||||
{"Header": "Customer Name", "HeaderRegex": "(?i)(cust(omer)?\\s?name)", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "Phone Number", "HeaderRegex": "(?i)phone\\s?(num(ber)?|#)?", "ValueRegex": "(\\+?\\d-?)?\\s?\\(?\\d{3}\\)?-?\\s?\\d{3}-?\\s?\\d{4}", "Nullable": false}, |
||||
{"Header": "Tax-ID", "HeaderRegex": "(?i)(tax-?id)|(TIN)|(EIN)", "ValueRegex": "(\\d{2}-?\\d{7})|((\\d{3}){2}\\d{3})|(\\d{3}-?\\d{2}-?\\d{4})", "Nullable": false}, |
||||
{"Header": "Debtor Address 1", "HeaderRegex": "(?i)debtor\\s?add(ress)?", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "Debtor City", "HeaderRegex": "(?i)debtor\\s?city", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "Debtor State", "HeaderRegex": "(?i)debtor\\s?state", "ValueRegex": "\\w+", "Nullable": false}, |
||||
{"Header": "Debtor Zip Code", "HeaderRegex": "(?i)debtor\\s?zip\\s?(code)?", "ValueRegex": "\\d{5}-?(\\d{4})?", "Nullable": false}, |
||||
{"Header": "Date Booked", "HeaderRegex": "(?i)date\\s?booked", "ValueRegex": "[1-2]?\\d\\/\\d{1,2}\\/(20)?\\d{2}", "Nullable": false}, |
||||
{"Header": "Term", "HeaderRegex": "(?i)term\\s?(\\(?months\\)?)?", "ValueRegex": "\\d{1,3}", "Nullable": false}, |
||||
{"Header": "Payment Amount", "HeaderRegex": "(?i)pa?yme?n?t\\s?am(oun)?t", "ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": false}, |
||||
{"Header": "Financed Amount", "HeaderRegex": "(?i)financed\\s?am(oun)?t", "ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": false}, |
||||
{"Header": "Receivable balance", "HeaderRegex": "(?i)rec(eivable)?\\s?bal(ance)?", "ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": false}, |
||||
{"Header": "Asset Description", "HeaderRegex": "(?i)asset\\sdesc(ription)?", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "Serial Number", "HeaderRegex": "(?i)serial\\s?num(ber)?|VIN", "ValueRegex": "\\d{8}", "Nullable": false}, |
||||
{"Header": "Business Type", "HeaderRegex": "(?i)(business|biz)\\s?type", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG Name", "HeaderRegex": "(?i)pg\\s?name", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG Address Line 1", "HeaderRegex": "(?i)pg\\s?add(ress)?", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG City", "HeaderRegex": "(?i)pg\\s?city", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG State", "HeaderRegex": "(?i)pg\\s?state", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG Zip", "HeaderRegex": "(?i)pg\\s?zip", "ValueRegex": "\\d{5}-?(\\d{4})?", "Nullable": false}, |
||||
{"Header": "PG SSN", "HeaderRegex": "(?i)pg\\s?ssn", "ValueRegex": "\\d{3}-?\\d{2}-?\\d{3}", "Nullable": false}, |
||||
{"Header": "DOB", "HeaderRegex": "(?i)Dob", "ValueRegex": "[0-2]?\\d\\/\\d{1,2}\\/(19|20)?\\d{2}", "Nullable": false}, |
||||
{"Header": "PG1 FICO", "HeaderRegex": "", "ValueRegex": "\\d{3}", "Nullable": false} |
||||
] |
||||
} |
||||
@ -0,0 +1,37 @@ |
||||
{ |
||||
"Logging": { |
||||
"LogLevel": { |
||||
"Default": "Information", |
||||
"Microsoft.AspNetCore": "Warning" |
||||
} |
||||
}, |
||||
"AllowedHosts": "*", |
||||
"Test" : "It Worked!", |
||||
"UploadSavePath": "../Uploaded/", |
||||
"DataStandard" : [ |
||||
{"Header": "Contract Number", "HeaderRegex": "PG1 FICO", "ValueRegex": "^\\d+\\d$", "Nullable": false}, |
||||
{"Header": "Customer Name", "HeaderRegex": "(?i)(cust(omer)?\\s?name)", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "Phone Number", "HeaderRegex": "(?i)phone\\s?(num(ber)?|#)?", "ValueRegex": "(\\+?\\d-?)?\\s?\\(?\\d{3}\\)?-?\\s?\\d{3}-?\\s?\\d{4}", "Nullable": false}, |
||||
{"Header": "Tax-ID", "HeaderRegex": "(?i)(tax-?id)|(TIN)|(EIN)", "ValueRegex": "(\\d{2}-?\\d{7})|((\\d{3}){2}\\d{3})|(\\d{3}-?\\d{2}-?\\d{4})", "Nullable": false}, |
||||
{"Header": "Debtor Address 1", "HeaderRegex": "(?i)debtor\\s?add(ress)?", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "Debtor City", "HeaderRegex": "(?i)debtor\\s?city", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "Debtor State", "HeaderRegex": "(?i)debtor\\s?state", "ValueRegex": "\\w+", "Nullable": false}, |
||||
{"Header": "Debtor Zip Code", "HeaderRegex": "(?i)debtor\\s?zip\\s?(code)?", "ValueRegex": "\\d{5}-?(\\d{4})?", "Nullable": false}, |
||||
{"Header": "Date Booked", "HeaderRegex": "(?i)date\\s?booked", "ValueRegex": "[1-2]?\\d\\/\\d{1,2}\\/(20)?\\d{2}", "Nullable": false}, |
||||
{"Header": "Term", "HeaderRegex": "(?i)term\\s?(\\(?months\\)?)?", "ValueRegex": "\\d{1,3}", "Nullable": false}, |
||||
{"Header": "Payment Amount", "HeaderRegex": "(?i)pa?yme?n?t\\s?am(oun)?t", "ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": false}, |
||||
{"Header": "Financed Amount", "HeaderRegex": "(?i)financed\\s?am(oun)?t", "ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": false}, |
||||
{"Header": "Receivable balance", "HeaderRegex": "(?i)rec(eivable)?\\s?bal(ance)?", "ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": false}, |
||||
{"Header": "Asset Description", "HeaderRegex": "(?i)asset\\sdesc(ription)?", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "Serial Number", "HeaderRegex": "(?i)serial\\s?num(ber)?|VIN", "ValueRegex": "\\d{8}", "Nullable": false}, |
||||
{"Header": "Business Type", "HeaderRegex": "(?i)(business|biz)\\s?type", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG Name", "HeaderRegex": "(?i)pg\\s?name", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG Address Line 1", "HeaderRegex": "(?i)pg\\s?add(ress)?", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG City", "HeaderRegex": "(?i)pg\\s?city", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG State", "HeaderRegex": "(?i)pg\\s?state", "ValueRegex": "(\\w+\\s?)+", "Nullable": false}, |
||||
{"Header": "PG Zip", "HeaderRegex": "(?i)pg\\s?zip", "ValueRegex": "\\d{5}-?(\\d{4})?", "Nullable": false}, |
||||
{"Header": "PG SSN", "HeaderRegex": "(?i)pg\\s?ssn", "ValueRegex": "\\d{3}-?\\d{2}-?\\d{3}", "Nullable": false}, |
||||
{"Header": "DOB", "HeaderRegex": "(?i)Dob", "ValueRegex": "[0-2]?\\d\\/\\d{1,2}\\/(19|20)?\\d{2}", "Nullable": false}, |
||||
{"Header": "PG1 FICO", "HeaderRegex": "", "ValueRegex": "\\d{3}", "Nullable": false} |
||||
] |
||||
} |
||||
@ -0,0 +1,19 @@ |
||||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
||||
|
||||
<PropertyGroup> |
||||
<TargetFramework>net7.0</TargetFramework> |
||||
<Nullable>enable</Nullable> |
||||
<ImplicitUsings>enable</ImplicitUsings> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup> |
||||
<PackageReference Include="ExcelDataReader" Version="3.7.0-develop00310" /> |
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.2" /> |
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.1" /> |
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> |
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.2" /> |
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> |
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
||||
@ -0,0 +1,53 @@ |
||||
<template> |
||||
<form> |
||||
<input type="file" id="uploadInput" accept=".xlsx" @change="upload($event)"> |
||||
</form> |
||||
</template> |
||||
|
||||
<script> |
||||
|
||||
import { read, utils } from "xlsx"; |
||||
|
||||
export default { |
||||
name: 'FileUpload', |
||||
data() { |
||||
return { |
||||
uploadedFiles: [], |
||||
uploadError: null, |
||||
currentStatus: null, |
||||
uploadFieldName: 'uploadfile' |
||||
} |
||||
}, |
||||
methods: { |
||||
async upload(event) { |
||||
|
||||
console.log("Upload method triggered!") |
||||
var file = await event.target.files[0].arrayBuffer(); |
||||
var workbook = read(file); |
||||
|
||||
var worksheet = workbook.Sheets[workbook.SheetNames[0]]; |
||||
|
||||
for(let col = 0; col<6; col++) { |
||||
var header; |
||||
var value; |
||||
for (let row = 5; row<7; row++) { |
||||
let adr = utils.encode_cell({c:col, r:row}) |
||||
let cell = worksheet[adr]; |
||||
if (row < 6 ){ |
||||
header = cell.v; |
||||
} else { value = cell.v; } |
||||
} |
||||
let datapoint = {h: header, v: value}; |
||||
console.log(datapoint) |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
</script> |
||||
@ -1,58 +0,0 @@ |
||||
<template> |
||||
<div class="hello"> |
||||
<h1>{{ msg }}</h1> |
||||
<p> |
||||
For a guide and recipes on how to configure / customize this project,<br> |
||||
check out the |
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>. |
||||
</p> |
||||
<h3>Installed CLI Plugins</h3> |
||||
<ul> |
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li> |
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li> |
||||
</ul> |
||||
<h3>Essential Links</h3> |
||||
<ul> |
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li> |
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li> |
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li> |
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li> |
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li> |
||||
</ul> |
||||
<h3>Ecosystem</h3> |
||||
<ul> |
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li> |
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li> |
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li> |
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li> |
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li> |
||||
</ul> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'HelloWorld', |
||||
props: { |
||||
msg: String |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
<style scoped> |
||||
h3 { |
||||
margin: 40px 0 0; |
||||
} |
||||
ul { |
||||
list-style-type: none; |
||||
padding: 0; |
||||
} |
||||
li { |
||||
display: inline-block; |
||||
margin: 0 10px; |
||||
} |
||||
a { |
||||
color: #42b983; |
||||
} |
||||
</style> |
||||
Loading…
Reference in new issue