Sistema de Códigos de Barras EAN-13

Plastico Tico Logo Sistema de Códigos de Barras EAN-13

Optimizado para Plastico Tico

📦 Productos

📁

Arrastra tu archivo Excel aquí

o haz clic para seleccionar

Formatos: .xlsx, .xls

ℹ️
Formato esperado:
• Una columna con “Referencia interna”
• Una columna con “Código de barras” (EAN-13)
* El sistema busca automáticamente estas columnas por nombre

🖼️ Vista Previa

📋

Carga el archivo Excel y selecciona un producto

La vista previa aparecerá aquí

`); doc.close(); // Restaurar botón setTimeout(() => { printZPLBtn.disabled = false; printZPLBtn.innerHTML = ' Imprimir vía ZPL'; }, 1000); showSuccessMessage(`✅ ZPL enviado a la impresora (${quantity} etiqueta${quantity > 1 ? 's' : ''})`); // Nota: En algunos casos, el navegador puede bloquear esto // Si no funciona, mostrar instrucciones alternativas setTimeout(() => { const shouldShowAlternative = confirm( '¿No se imprimió?\n\n' + 'Los navegadores a veces bloquean la impresión directa de ZPL.\n\n' + '¿Deseas descargar el archivo ZPL para enviarlo manualmente?' ); if (shouldShowAlternative) { // Crear archivo .zpl para descargar const blob = new Blob([zplCommands], { type: 'application/zpl' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `etiqueta_${selectedProduct.reference}_${quantity}.zpl`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); // Mostrar instrucciones simples alert( '📄 Archivo ZPL descargado\n\n' + 'MÉTODO RÁPIDO:\n' + '1. Abre Command Prompt (CMD)\n' + '2. Arrastra el archivo .zpl a la ventana\n' + '3. Agrega al final: > \\\\localhost\\nombre_impresora\n' + '4. Presiona Enter\n\n' + 'O simplemente arrastra el archivo .zpl sobre el ícono de tu impresora.' ); } }, 3000); } catch (error) { console.error('Error al generar ZPL:', error); alert('❌ Error al generar código ZPL. Por favor intenta de nuevo.'); // Restaurar botón printZPLBtn.disabled = false; printZPLBtn.innerHTML = ' Imprimir vía ZPL'; } }); // Descargar como imágenes downloadImgBtn.addEventListener('click', async () => { if (!selectedProduct) return; const quantity = parseInt(quantityInput.value) || 1; // Deshabilitar botón y mostrar progreso downloadImgBtn.disabled = true; downloadImgBtn.innerHTML = ' Generando imágenes en alta calidad...'; try { // Crear un canvas temporal para cada etiqueta for (let i = 0; i < quantity; i++) { // Crear canvas con ALTA RESOLUCIÓN para impresión // 300 DPI para calidad profesional: 1mm = 11.81 pixels const DPI_SCALE = 11.81; // 300 DPI const pixelWidth = Math.round(labelConfig.width * DPI_SCALE); const pixelHeight = Math.round(labelConfig.height * DPI_SCALE); const canvas = document.createElement('canvas'); canvas.width = pixelWidth; canvas.height = pixelHeight; const ctx = canvas.getContext('2d'); // Habilitar suavizado de alta calidad ctx.imageSmoothingEnabled = true; ctx.imageSmoothingQuality = 'high'; // Fondo blanco ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Calcular tamaños proporcionales const titleFontSize = Math.round(labelConfig.titleSize * 3.15); // Escalar título const marginTop = Math.round(labelConfig.marginTop * DPI_SCALE); const marginSide = Math.round(labelConfig.marginSide * DPI_SCALE); // Dibujar título con mayor calidad ctx.fillStyle = '#000000'; ctx.font = `bold ${titleFontSize}px Arial, sans-serif`; ctx.textAlign = 'center'; ctx.textBaseline = 'top'; // Dibujar el título const titleY = marginTop + 20; ctx.fillText(selectedProduct.reference, canvas.width / 2, titleY); // Crear canvas temporal para el código de barras a ALTA RESOLUCIÓN const barcodeCanvas = document.createElement('canvas'); // Escalar parámetros del código de barras para alta resolución const barcodeWidth = labelConfig.barcodeWidth * 3.15; // Mayor grosor const barcodeHeight = Math.round(labelConfig.barcodeHeight * DPI_SCALE * 0.8); // Altura proporcional const barcodeFontSize = Math.round(labelConfig.fontSize * 3.15); JsBarcode(barcodeCanvas, selectedProduct.barcode, { format: "EAN13", width: barcodeWidth, height: barcodeHeight, displayValue: true, fontSize: barcodeFontSize, margin: Math.round(5 * DPI_SCALE / 11.81), marginTop: Math.round(5 * DPI_SCALE / 11.81), marginBottom: Math.round(5 * DPI_SCALE / 11.81), background: "#ffffff", lineColor: "#000000", fontOptions: "bold" }); // Centrar y posicionar el código de barras const barcodeX = (canvas.width - barcodeCanvas.width) / 2; const barcodeY = titleY + titleFontSize + Math.round(15 * DPI_SCALE / 11.81); // Dibujar código de barras con alta calidad ctx.drawImage(barcodeCanvas, barcodeX, barcodeY); // Convertir a PNG de ALTA CALIDAD y descargar canvas.toBlob((blob) => { const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `etiqueta_${selectedProduct.reference}_${selectedProduct.barcode}_${i + 1}.png`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }, 'image/png', 1.0); // Calidad máxima // Pequeña pausa entre descargas await new Promise(resolve => setTimeout(resolve, 250)); } // Restaurar botón downloadImgBtn.disabled = false; downloadImgBtn.innerHTML = '📥 Descargar como Imágenes'; showSuccessMessage(`✅ ${quantity} imagen${quantity > 1 ? 'es' : ''} de alta calidad descargada${quantity > 1 ? 's' : ''} (300 DPI)`); } catch (error) { console.error('Error al generar imágenes:', error); alert('❌ Error al generar las imágenes. Por favor intenta de nuevo.'); // Restaurar botón downloadImgBtn.disabled = false; downloadImgBtn.innerHTML = '📥 Descargar como Imágenes'; } }); // Descargar TODOS los productos downloadAllBtn.addEventListener('click', async () => { if (products.length === 0) { alert('⚠️ Primero carga el archivo Excel con los productos'); return; } const confirmDownload = confirm( `¿Deseas generar etiquetas para TODOS los ${products.length} productos?\n\n` + `Esto puede tomar varios minutos.\n\n` + `Se crearán ${products.length} imágenes PNG de alta calidad (300 DPI).` ); if (!confirmDownload) return; // Deshabilitar botón y mostrar progreso downloadAllBtn.disabled = true; downloadAllBtn.innerHTML = ' Generando... 0/' + products.length; try { const zip = new JSZip(); const folder = zip.folder("etiquetas_codigos_barras"); // Generar una imagen para cada producto for (let i = 0; i < products.length; i++) { const product = products[i]; try { // Actualizar progreso downloadAllBtn.innerHTML = ` Generando... ${i + 1}/${products.length}`; // Crear canvas con ALTA RESOLUCIÓN const DPI_SCALE = 11.81; // 300 DPI const pixelWidth = Math.round(labelConfig.width * DPI_SCALE); const pixelHeight = Math.round(labelConfig.height * DPI_SCALE); const canvas = document.createElement('canvas'); canvas.width = pixelWidth; canvas.height = pixelHeight; const ctx = canvas.getContext('2d'); // Habilitar suavizado de alta calidad ctx.imageSmoothingEnabled = true; ctx.imageSmoothingQuality = 'high'; // Fondo blanco ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Calcular tamaños proporcionales const titleFontSize = Math.round(labelConfig.titleSize * 3.15); const marginTop = Math.round(labelConfig.marginTop * DPI_SCALE); // Dibujar título ctx.fillStyle = '#000000'; ctx.font = `bold ${titleFontSize}px Arial, sans-serif`; ctx.textAlign = 'center'; ctx.textBaseline = 'top'; const titleY = marginTop + 20; ctx.fillText(product.reference, canvas.width / 2, titleY); // Crear canvas temporal para el código de barras const barcodeCanvas = document.createElement('canvas'); const barcodeWidth = labelConfig.barcodeWidth * 3.15; const barcodeHeight = Math.round(labelConfig.barcodeHeight * DPI_SCALE * 0.8); const barcodeFontSize = Math.round(labelConfig.fontSize * 3.15); JsBarcode(barcodeCanvas, product.barcode, { format: "EAN13", width: barcodeWidth, height: barcodeHeight, displayValue: true, fontSize: barcodeFontSize, margin: Math.round(5 * DPI_SCALE / 11.81), marginTop: Math.round(5 * DPI_SCALE / 11.81), marginBottom: Math.round(5 * DPI_SCALE / 11.81), background: "#ffffff", lineColor: "#000000", fontOptions: "bold" }); // Centrar y posicionar el código de barras const barcodeX = (canvas.width - barcodeCanvas.width) / 2; const barcodeY = titleY + titleFontSize + Math.round(15 * DPI_SCALE / 11.81); // Dibujar código de barras ctx.drawImage(barcodeCanvas, barcodeX, barcodeY); // Convertir canvas a blob PNG const dataURL = canvas.toDataURL('image/png', 1.0); const base64Data = dataURL.split(',')[1]; // Agregar al ZIP con nombre limpio (sanitizar nombre) const safeName = product.reference.replace(/[^a-zA-Z0-9\-\_]/g, '_'); const filename = `${safeName}_${product.barcode}.png`; folder.file(filename, base64Data, {base64: true}); } catch (error) { console.error(`Error en producto ${i + 1} (${product.reference}):`, error); // Continuar con el siguiente producto } // Pequeña pausa para no bloquear el navegador if (i % 10 === 0) { await new Promise(resolve => setTimeout(resolve, 10)); } } // Generar el archivo ZIP downloadAllBtn.innerHTML = ' Creando archivo ZIP...'; const zipBlob = await zip.generateAsync({ type: "blob", compression: "DEFLATE", compressionOptions: { level: 6 } }); // Descargar el ZIP const fecha = new Date().toISOString().split('T')[0]; saveAs(zipBlob, `etiquetas_codigos_barras_${fecha}.zip`); // Restaurar botón downloadAllBtn.disabled = false; downloadAllBtn.innerHTML = '📦 Descargar TODOS los Productos'; showSuccessMessage(`✅ ${products.length} etiquetas descargadas en formato ZIP`); } catch (error) { console.error('Error al generar ZIP:', error); alert('❌ Error al generar el archivo ZIP. Por favor intenta de nuevo.'); // Restaurar botón downloadAllBtn.disabled = false; downloadAllBtn.innerHTML = '📦 Descargar TODOS los Productos'; } }); // Mostrar estadísticas function showStats() { stats.style.display = 'grid'; updateStats(); } function updateStats() { document.getElementById('totalProducts').textContent = products.length; document.getElementById('selectedCount').textContent = selectedProduct ? 1 : 0; document.getElementById('totalToPrint').textContent = selectedProduct ? (parseInt(quantityInput.value) || 1) : 0; }