Download excel-fix-100px.js from bep40/V.AISTUDIO: direct link, hf CLI and curl.
- Browser
- Download file 6.1 kB
-
https://huggingface.co/bep40/V.AISTUDIO/resolve/main/excel-fix-100px.js
- Command line
-
hf download hf://bep40/V.AISTUDIO/excel-fix-100px.js
-
curl -L -o excel-fix-100px.js https://huggingface.co/bep40/V.AISTUDIO/resolve/main/excel-fix-100px.js
6.1 kB
| /** | |
| * V.AI STUDIO - Excel Export v1102 | |
| * FIX: Hình ảnh 100x100px trong Excel | |
| */ | |
| (function(){ | |
| ; | |
| function fmt(n){ | |
| if(n==null||n==='')return'0đ'; | |
| var num=typeof n==='string'?parseFloat(n.replace(/[^\d.-]/g,'')):Number(n); | |
| if(isNaN(num))return'0đ'; | |
| return num.toLocaleString('vi-VN')+'đ'; | |
| } | |
| async function fetchImageArrayBuffer(url){ | |
| if(!url||!url.startsWith('http')) return null; | |
| try{ | |
| var r = await fetch(url,{mode:'cors'}); | |
| if(r.ok) return await r.arrayBuffer(); | |
| }catch(e){} | |
| try{ | |
| var r2 = await fetch('https://api.allorigins.win/raw?url=' + encodeURIComponent(url)); | |
| if(r2.ok) return await r2.arrayBuffer(); | |
| }catch(e){} | |
| return null; | |
| } | |
| function getOrderCode(){ | |
| var n = document.getElementById('quoteName')?.value || ''; | |
| var h = window.location.hash; | |
| var today = new Date(), dd=today.getDate().toString().padStart(2,'0'), mm=(today.getMonth()+1).toString().padStart(2,'0'), yy=today.getFullYear().toString().slice(-2); | |
| var ini=''; | |
| if(n && n.trim()){ | |
| n.trim().split(/\s+/).forEach(function(w){ | |
| if(w && /[A-Z]/.test(w.charAt(0).toUpperCase())) ini += w.charAt(0).toUpperCase(); | |
| }); | |
| } | |
| return 'VAS'+(ini||'X')+dd+mm+yy; | |
| } | |
| window.exportExcel = async function(){ | |
| var cart = window.cart || []; | |
| if(!cart.length){alert('Giỏ trống!');return;} | |
| if(typeof ExcelJS === 'undefined'){ | |
| var s = document.createElement('script'); | |
| s.src = 'https://cdn.jsdelivr.net/npm/exceljs@4.4.0/dist/exceljs.min.js'; | |
| document.head.appendChild(s); | |
| await new Promise(function(r){s.onload=r}); | |
| } | |
| try{ | |
| var code = getOrderCode(); | |
| var wb = new ExcelJS.Workbook(), ws = wb.addWorksheet('Báo giá'); | |
| // Column 2 width 15 for 100px image | |
| ws.columns = [ | |
| {width:6},{width:15},{width:30},{width:15}, | |
| {width:22},{width:8},{width:15},{width:15},{width:18},{width:16} | |
| ]; | |
| // Header title | |
| ws.mergeCells('A1:J1'); | |
| ws.getCell('A1').value = 'BẢNG BÁO GIÁ'; | |
| ws.getCell('A1').font = {bold:true, size:18, color:{argb:'FFDB9815'}}; | |
| ws.getCell('A1').alignment = {horizontal:'center'}; | |
| ws.getRow(1).height = 30; | |
| // Table header | |
| var hr = ws.getRow(3); | |
| ['STT','Hình','Tên sản phẩm','Mã SP','Thông tin','SL','Đơn giá','Giá CK','Thành tiền','Ghi chú'].forEach(function(h,i){ | |
| var c = hr.getCell(i+1); | |
| c.value = h; | |
| c.font = {bold:true, color:{argb:'FFFFFFFF'}, size:9}; | |
| c.fill = {type:'pattern', pattern:'solid', fgColor:{argb:'FF003F62'}}; | |
| c.alignment = {horizontal:'center', vertical:'middle'}; | |
| }); | |
| hr.height = 20; | |
| // Items with 100x100px images | |
| var firstRow = 5; | |
| await Promise.all(cart.map(async function(c, i){ | |
| var p = window.D && D[c.idx] ? D[c.idx] : null; | |
| var row = ws.getRow(firstRow + i); | |
| row.height = 120; // 100px + padding | |
| var bgColor = i % 2 === 0 ? 'FFF8FAFC' : 'FFFFFFFF'; | |
| row.getCell(1).value = i+1; | |
| row.getCell(1).alignment = {horizontal:'center', vertical:'middle'}; | |
| // IMAGE 100x100px | |
| if((p && p.image) || c.image){ | |
| var imgUrl = p?.image || c.image; | |
| var imgBuf = await fetchImageArrayBuffer(imgUrl); | |
| if(imgBuf){ | |
| try{ | |
| wb.addImage(wb.addImage({buffer:imgBuf, extension:'png'}), | |
| {tl:{col:1, row:firstRow+i-1}, ext:{width:100, height:100}}); | |
| }catch(e){} | |
| } | |
| } | |
| row.getCell(3).value = c.name || (p?p.name||p.n:'') || ''; | |
| row.getCell(3).font = {bold:true, size:9}; | |
| row.getCell(4).value = c.sku || (p?p.sku||p.model:'') || ''; | |
| row.getCell(6).value = Number(c.qty||1); | |
| row.getCell(7).value = Number(c.priceNum||(p?p.priceNum:0)||0); | |
| row.getCell(7).numFmt = '#,##0"đ"'; | |
| row.getCell(8).value = Number(c.priceNum||(p?p.priceNum:0)||0); | |
| row.getCell(8).numFmt = '#,##0"đ"'; | |
| row.getCell(9).value = Number(c.priceNum||(p?p.priceNum:0)||0) * Number(c.qty||1); | |
| row.getCell(9).numFmt = '#,##0"đ"'; | |
| for(var ci=1; ci<=10; ci++){ | |
| row.getCell(ci).fill = {type:'pattern', pattern:'solid', fgColor:{argb:bgColor}}; | |
| } | |
| })); | |
| var lastRow = firstRow + cart.length - 1; | |
| // Total row | |
| ws.getCell('A'+(lastRow+2)).value = 'TỔNG CỘNG'; | |
| ws.getCell('A'+(lastRow+2)).font = {bold:true, size:13, color:{argb:'FFFFFFFF'}}; | |
| ws.getCell('A'+(lastRow+2)).fill = {type:'pattern', pattern:'solid', fgColor:{argb:'FF003F62'}}; | |
| ws.getCell('I'+(lastRow+2)).value = {formula:'SUM(I'+firstRow+':I'+lastRow+')'}; | |
| ws.getCell('I'+(lastRow+2)).numFmt = '#,##0"đ"'; | |
| ws.getCell('I'+(lastRow+2)).font = {bold:true, size:14, color:{argb:'FFF0B840'}}; | |
| wb.calcProperties.fullCalcOnLoad = true; | |
| var buf = await wb.xlsx.writeBuffer(); | |
| var blob = new Blob([buf], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}); | |
| var url = URL.createObjectURL(blob); | |
| var a = document.createElement('a'); | |
| a.href = url; | |
| a.download = code + '.xlsx'; | |
| document.body.appendChild(a); | |
| a.click(); | |
| setTimeout(function(){ document.body.removeChild(a); URL.revokeObjectURL(url); }, 30000); | |
| console.log('[VAI] Excel export OK - hình ảnh 100px'); | |
| if(typeof showToast === 'function') showToast('✅ Excel OK - Hình ảnh 100px'); | |
| }catch(e){ | |
| console.error('[VAI] Excel error:', e); | |
| alert('Lỗi: '+e.message); | |
| } | |
| }; | |
| console.log('[VAI v1102] Excel fix loaded - 100px images ready'); |