const JSZip = require('jszip'); const fs = require('fs'); const path = require('path'); // EMU to inches: 1 inch = 914400 EMU // Slide: 9144000 x 5143500 EMU = 10" x 5.625" const EMU = 914400; const SLIDE_W = 9144000; const SLIDE_H = 5143500; const SCALE = 960 / 10; // 96px per inch (at 100%) function emuToPx(emu) { return (emu / EMU) * SCALE; } function hexToRgb(hex) { if (!hex || hex.length < 6) return '#888888'; return '#' + hex.slice(-6); } async function renderSlideHtml(xml, slideNum) { // Extract background color const bgMatch = xml.match(/p:bg>.*?(.+?)<\/p:sp>/gs; let spMatch; while ((spMatch = spPattern.exec(xml)) !== null) { const spXml = spMatch[1]; // Get position const offMatch = spXml.match(/([\s\S]*?)<\/a:p>/g; let paraMatch; while ((paraMatch = paraPattern.exec(spXml)) !== null) { const paraXml = paraMatch[1]; const textMatches = [...paraXml.matchAll(/]*>([^<]*)<\/a:t>/g)]; const paraText = textMatches.map(m => m[1]).join(''); if (paraText.trim()) texts.push(paraText.trim()); } // Get font size const szMatch = spXml.match(/sz="(\d+)"/); const fontSize = szMatch ? parseInt(szMatch[1]) / 100 : 12; // Get text color const txtColorMatch = spXml.match(/[\s\S]*?'); shapesHtml += `
${textContent}
`; } return `
${slideNum}
${shapesHtml}
`; } async function createPreview(pptxPath, outputPath) { const data = fs.readFileSync(pptxPath); const zip = await JSZip.loadAsync(data); const slideFiles = Object.keys(zip.files) .filter(f => f.match(/^ppt\/slides\/slide\d+\.xml$/)) .sort((a, b) => { const na = parseInt(a.match(/slide(\d+)/)[1]); const nb = parseInt(b.match(/slide(\d+)/)[1]); return na - nb; }); let slidesHtml = ''; for (const sf of slideFiles) { const slideNum = parseInt(sf.match(/slide(\d+)/)[1]); const xml = await zip.file(sf).async('string'); slidesHtml += await renderSlideHtml(xml, slideNum); } const html = ` ${path.basename(pptxPath)}

${path.basename(pptxPath)}

${slidesHtml}
`; fs.writeFileSync(outputPath, html); console.log(`Preview: ${outputPath} (${slideFiles.length} slides)`); } (async () => { await createPreview( 'E:/test/삼성디스플레이 vs LG디스플레이 비교 분석 보고서_20260407_1958.pptx', 'C:/Users/admin/AppData/Local/Temp/pptx_gen/preview1.html' ); await createPreview( 'E:/test/삼성디스플레이 사업 영역 및 제품 강점 분석 보고서_20260407_1956.pptx', 'C:/Users/admin/AppData/Local/Temp/pptx_gen/preview2.html' ); })();