/** * HTML Generator Utility * 用于生成幻灯片的 HTML 内容 */ /** * 生成幻灯片的 HTML 内容 * @param {Object} slideData - 幻灯片数据 * @param {number} slideIndex - 幻灯片索引 * @param {Object} options - 渲染选项 * @returns {string} HTML 字符串 */ export function generateSlideHTML(slideData, slideIndex = 0, options = {}) { const { width = 1000, height = 562, backgroundColor = '#ffffff', scale = 1 } = options; if (!slideData || !slideData.slides || !slideData.slides[slideIndex]) { throw new Error(`Invalid slide data or slide index: ${slideIndex}`); } const slide = slideData.slides[slideIndex]; const slideBackground = slide.background || backgroundColor; // 生成元素的 HTML const elementsHTML = generateElementsHTML(slide.elements || [], { width, height, scale }); return ` Slide ${slideIndex + 1}
${elementsHTML}
`.trim(); } /** * 生成元素的 HTML * @param {Array} elements - 元素数组 * @param {Object} options - 渲染选项 * @returns {string} 元素 HTML 字符串 */ function generateElementsHTML(elements, options = {}) { if (!Array.isArray(elements)) { return ''; } return elements.map(element => { try { return generateElementHTML(element, options); } catch (error) { console.warn(`Failed to generate HTML for element:`, element, error); return ''; } }).join('\n'); } /** * 生成单个元素的 HTML * @param {Object} element - 元素数据 * @param {Object} options - 渲染选项 * @returns {string} 元素 HTML 字符串 */ function generateElementHTML(element, options = {}) { if (!element || typeof element !== 'object') { return ''; } const { type, left = 0, top = 0, width = 100, height = 100, rotate = 0, opacity = 1 } = element; const baseStyle = ` left: ${left}px; top: ${top}px; width: ${width}px; height: ${height}px; transform: rotate(${rotate}deg); opacity: ${opacity}; `; switch (type) { case 'text': return generateTextElementHTML(element, baseStyle); case 'image': return generateImageElementHTML(element, baseStyle); case 'shape': return generateShapeElementHTML(element, baseStyle); case 'line': return generateLineElementHTML(element, baseStyle); case 'chart': return generateChartElementHTML(element, baseStyle); case 'table': return generateTableElementHTML(element, baseStyle); default: console.warn(`Unknown element type: ${type}`); return ''; } } /** * 生成文本元素 HTML */ function generateTextElementHTML(element, baseStyle) { const { content = '', fontSize = 14, fontFamily = 'Arial', color = '#000000', fontWeight = 'normal', fontStyle = 'normal', textDecoration = 'none', textAlign = 'left', lineHeight = 1.2 } = element; const textStyle = ` font-size: ${fontSize}px; font-family: ${fontFamily}; color: ${color}; font-weight: ${fontWeight}; font-style: ${fontStyle}; text-decoration: ${textDecoration}; text-align: ${textAlign}; line-height: ${lineHeight}; `; return `
${escapeHtml(content)}
`; } /** * 生成图片元素 HTML */ function generateImageElementHTML(element, baseStyle) { const { src = '', alt = '' } = element; if (!src) { return `
图片加载失败
`; } return `
${escapeHtml(alt)}
`; } /** * 生成形状元素 HTML */ function generateShapeElementHTML(element, baseStyle) { const { fill = '#ffffff', stroke = '#000000', strokeWidth = 1, borderRadius = 0 } = element; const shapeStyle = ` background: ${fill}; border: ${strokeWidth}px solid ${stroke}; border-radius: ${borderRadius}px; `; return `
`; } /** * 生成线条元素 HTML */ function generateLineElementHTML(element, baseStyle) { const { stroke = '#000000', strokeWidth = 2 } = element; const lineStyle = ` background: ${stroke}; height: ${strokeWidth}px; color: ${stroke}; `; return `
`; } /** * 生成图表元素 HTML */ function generateChartElementHTML(element, baseStyle) { // 简化的图表渲染,实际项目中可能需要更复杂的图表库 return `
📊 图表
`; } /** * 生成表格元素 HTML */ function generateTableElementHTML(element, baseStyle) { const { data = [] } = element; if (!Array.isArray(data) || data.length === 0) { return `
📋 空表格
`; } const tableHTML = data.map(row => { if (!Array.isArray(row)) return ''; const cellsHTML = row.map(cell => `${escapeHtml(String(cell))}`).join(''); return `${cellsHTML}`; }).join(''); return `
${tableHTML}
`; } /** * HTML 转义函数 * @param {string} text - 需要转义的文本 * @returns {string} 转义后的文本 */ function escapeHtml(text) { if (typeof text !== 'string') { return String(text); } const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, m => map[m]); } /** * 生成完整的 PPT HTML(包含所有幻灯片) * @param {Object} pptData - PPT 数据 * @param {Object} options - 渲染选项 * @returns {string} 完整的 HTML 字符串 */ export function generatePPTHTML(pptData, options = {}) { if (!pptData || !pptData.slides || !Array.isArray(pptData.slides)) { throw new Error('Invalid PPT data'); } const { width = 1000, height = 562 } = options; const slidesHTML = pptData.slides.map((slide, index) => { try { return generateSlideHTML(pptData, index, options); } catch (error) { console.warn(`Failed to generate HTML for slide ${index}:`, error); return `
幻灯片 ${index + 1} 渲染失败
`; } }).join('\n\n'); return ` PPT Preview
${slidesHTML}
`.trim(); } export default { generateSlideHTML, generatePPTHTML };