247 lines
5.7 KiB
HTML
247 lines
5.7 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>PART – Excel Import</title>
|
||
|
||
<script src="/backend/xlsx/xlsx.full.min.js"></script>
|
||
<script src="/backend/handsontable/handsontable/dist/handsontable.full.min.js"></script>
|
||
<link rel="stylesheet" href="/backend/handsontable/handsontable/dist/handsontable.full.min.css">
|
||
|
||
<style>
|
||
/* ===== BASE THEME (Workbench / HMI) ===== */
|
||
:root{
|
||
--bg:#0b1020;
|
||
--card:rgba(255,255,255,0.08);
|
||
--border:rgba(255,255,255,0.14);
|
||
--text:rgba(255,255,255,0.92);
|
||
--muted:rgba(255,255,255,0.6);
|
||
--accent:#4f7cff;
|
||
--shadow:0 16px 60px rgba(0,0,0,.4);
|
||
--radius:20px;
|
||
}
|
||
|
||
*{box-sizing:border-box}
|
||
html,body{height:100%}
|
||
|
||
body{
|
||
margin:0;
|
||
padding:16px;
|
||
font-family:-apple-system,system-ui,Segoe UI,Roboto;
|
||
background:
|
||
radial-gradient(900px 600px at 20% 10%, rgba(79,124,255,.35), transparent 60%),
|
||
var(--bg);
|
||
color:var(--text);
|
||
}
|
||
|
||
/* ===== LAYOUT ===== */
|
||
.app{
|
||
max-width:1400px;
|
||
margin:0 auto;
|
||
height:100%;
|
||
display:grid;
|
||
grid-template-rows:auto 1fr;
|
||
gap:16px;
|
||
}
|
||
|
||
.panel{
|
||
background:linear-gradient(180deg,var(--card),rgba(255,255,255,.04));
|
||
border:1px solid var(--border);
|
||
border-radius:var(--radius);
|
||
box-shadow:var(--shadow);
|
||
overflow:hidden;
|
||
}
|
||
|
||
.header{
|
||
padding:14px 18px;
|
||
display:flex;
|
||
align-items:center;
|
||
justify-content:space-between;
|
||
border-bottom:1px solid var(--border);
|
||
}
|
||
|
||
.header h1{
|
||
margin:0;
|
||
font-size:18px;
|
||
}
|
||
|
||
/* ===== CONTENT ===== */
|
||
.content{
|
||
padding:16px;
|
||
display:flex;
|
||
flex-direction:column;
|
||
gap:14px;
|
||
height:100%;
|
||
}
|
||
|
||
/* ===== ACTION BAR ===== */
|
||
.actions{
|
||
display:flex;
|
||
gap:12px;
|
||
align-items:center;
|
||
}
|
||
|
||
input[type="file"]{
|
||
color:var(--muted);
|
||
}
|
||
|
||
/* ===== BUTTONS ===== */
|
||
button{
|
||
padding:10px 18px;
|
||
border-radius:14px;
|
||
border:0;
|
||
background:var(--accent);
|
||
color:#fff;
|
||
font-size:14px;
|
||
cursor:pointer;
|
||
}
|
||
|
||
button.secondary{
|
||
background:rgba(255,255,255,.12);
|
||
}
|
||
|
||
button:hover{
|
||
filter:brightness(1.1);
|
||
}
|
||
|
||
/* ===== HANDSONTABLE ===== */
|
||
#import-table{
|
||
flex:1;
|
||
overflow:hidden;
|
||
border-radius:14px;
|
||
border:1px solid var(--border);
|
||
}
|
||
|
||
.handsontable{
|
||
background:transparent;
|
||
}
|
||
|
||
.ht_master .wtHolder{
|
||
background:transparent;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<main class="app">
|
||
|
||
<!-- HEADER -->
|
||
<section class="panel">
|
||
<div class="header">
|
||
<h1>PART – Excel Import / Export</h1>
|
||
<div class="actions">
|
||
<button id="export-button" class="secondary">Excel Export</button>
|
||
<button id="send-button">Daten senden</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- CONTENT -->
|
||
<section class="panel content">
|
||
<div class="actions">
|
||
<input type="file" id="file-input" accept=".xlsx">
|
||
</div>
|
||
<div id="import-table"></div>
|
||
</section>
|
||
|
||
</main>
|
||
|
||
<script>
|
||
document.addEventListener("DOMContentLoaded", function () {
|
||
let importedData = [];
|
||
let hot;
|
||
|
||
const url = sessionStorage.getItem("url");
|
||
const stationNumber = sessionStorage.getItem("stationNumber");
|
||
|
||
function exportExcel() {
|
||
const headers = [
|
||
"Artikelnummer",
|
||
"Artikelbeschreibung",
|
||
"Artikelgruppe",
|
||
"Materialcode",
|
||
"Einheit",
|
||
"Produktflag"
|
||
];
|
||
const worksheet = XLSX.utils.aoa_to_sheet([headers]);
|
||
const workbook = XLSX.utils.book_new();
|
||
XLSX.utils.book_append_sheet(workbook, worksheet, "Artikel");
|
||
XLSX.writeFile(workbook, "ArtikelExport.xlsx");
|
||
}
|
||
|
||
function importExcelData() {
|
||
const fileInput = document.getElementById("file-input");
|
||
if (!fileInput.files.length) return;
|
||
|
||
const reader = new FileReader();
|
||
reader.onload = function (event) {
|
||
const workbook = XLSX.read(event.target.result, { type: "binary" });
|
||
const sheet = workbook.Sheets[workbook.SheetNames[0]];
|
||
importedData = XLSX.utils.sheet_to_json(sheet, { header: 1 })
|
||
.slice(1)
|
||
.filter(row =>
|
||
Array.isArray(row) &&
|
||
row.some(cell => cell !== null && cell !== undefined && String(cell).trim() !== "")
|
||
);
|
||
|
||
if (hot) {
|
||
hot.loadData(importedData);
|
||
} else {
|
||
hot = new Handsontable(document.getElementById("import-table"), {
|
||
data: importedData,
|
||
colHeaders: [
|
||
"MATERIAL_NO",
|
||
"MATERIAL_DESC",
|
||
"MATERIAL_GRP_NO",
|
||
"MATERIAL_GRP_TYPE",
|
||
"UNIT",
|
||
"PRODUCT"
|
||
],
|
||
rowHeaders: true,
|
||
width: "100%",
|
||
height: "100%",
|
||
licenseKey: "non-commercial-and-evaluation"
|
||
});
|
||
}
|
||
};
|
||
reader.readAsBinaryString(fileInput.files[0]);
|
||
}
|
||
|
||
function sendExcelData() {
|
||
const jsonData = importedData.map(row => ({
|
||
MATERIAL_NO: "" + row[0],
|
||
MATERIAL_DESC: "" + row[1],
|
||
MATERIAL_GRP_NO: "" + row[2],
|
||
MATERIAL_GRP_TYPE: "" + row[3],
|
||
UNIT: "" + row[4],
|
||
PRODUCT: "" + row[5]
|
||
}));
|
||
|
||
if (!url) {
|
||
alert("Backend URL is not defined.");
|
||
return;
|
||
}
|
||
|
||
fetch(url + "/backend/api/updateParts", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ station: stationNumber, data: jsonData })
|
||
})
|
||
.then(r => {
|
||
if (!r.ok) throw new Error(r.status);
|
||
return r.json();
|
||
})
|
||
.then(() => alert("Daten erfolgreich gesendet!"))
|
||
.catch(err => alert("Fehler beim Senden: " + err.message));
|
||
}
|
||
|
||
document.getElementById("export-button").addEventListener("click", exportExcel);
|
||
document.getElementById("file-input").addEventListener("change", importExcelData);
|
||
document.getElementById("send-button").addEventListener("click", sendExcelData);
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|