UNPKG

pptxgenjs

Version:

JavaScript library that creates PowerPoint presentations

1,117 lines (1,020 loc) 49.1 kB
<!DOCTYPE html> <html lang="en-us"> <head> <title>PptxGenJS Examples/Demo Page</title> <meta http-equiv="X-UA-Compatible" content="IE=edge;chrome=1"> <meta name="author" content="https://github.com/gitbrent"> <meta name="date" content="20180820"> <link href="https://fonts.googleapis.com/css?family=Roboto:100,300|Roboto+Mono|Open+Sans" rel="stylesheet"> <!-- IE11 Users: - Use the following 3 lines instead of the one above <link href="https://fonts.googleapis.com/css?family=Roboto:100" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"> --> <link rel="stylesheet" href="https://cdn.rawgit.com/gitbrent/PptxGenJS/v2.2.0/examples/pptxgenjs-demo.css"> <!-- NOTE: 1) Running this on your local PC requires Chrome be run from the console/terminal in order to allow reading local image files $ open -a 'Google Chrome' -\-args -\-allow-file-access-from-files & (Otherwise you will receive: "Tainted canvases may not be exported" message in console) 2) IE11 will show an "Active-X blocked on this page, do you want to allow?" security dialog when run locally (run from server to remedy) --> <script src="https://cdn.rawgit.com/gitbrent/PptxGenJS/v2.2.0/examples/images/base64Images.js"></script> <script src="https://cdn.rawgit.com/gitbrent/PptxGenJS/v2.2.0/examples/media/base64media.js"></script> <script src="https://cdn.rawgit.com/gitbrent/PptxGenJS/v2.2.0/dist/pptxgen.colors.js"></script> <script src="https://cdn.rawgit.com/gitbrent/PptxGenJS/v2.2.0/dist/pptxgen.shapes.js"></script> <!-- RELEASE (CDN) --> <script src="https://cdn.rawgit.com/gitbrent/PptxGenJS/9aaed1d5/dist/pptxgen.bundle.js"></script> <script src="https://cdn.rawgit.com/gitbrent/PptxGenJS/9aaed1d5/examples/pptxgenjs-demo.js"></script> <!-- OFFICE365 TESTING: <script src="../SiteAssets/pptxgenjs/libs/jquery.min.js"></script> <script src="../SiteAssets/pptxgenjs/libs/jszip.min.js"></script> <script src="../SiteAssets/pptxgenjs/dist/pptxgen.js"></script> <script src="../SiteAssets/pptxgenjs/examples/pptxgenjs-demo.js"></script> --> <!-- LOCAL TESTING: <script src="../libs/promise.min.js"></script> <script src="../libs/jquery.min.js"></script> <script src="../libs/jszip.min.js"></script> <script src="../dist/pptxgen.js"></script> <script src="../examples/pptxgenjs-demo.js"></script> --> <script> // ================================================================================================================== function doNav(intTab) { location.href = '#tab'+intTab; doNavRestore(); } function doNavRestore() { if ( window.location.href.toLowerCase().indexOf('#tab') > -1 ) { var tabNum = window.location.href.toLowerCase().split('#tab')[1]; $('#navTabs').find('> div, li').removeClass('active'); $('#navTabs li#nav'+tabNum).addClass('active'); $('#tab'+tabNum).addClass('active'); } } /* DESC: old/undocumented/unused */ function doTestSimple() { var pptx = new PptxGenJS(); var slide = pptx.addNewSlide(); var optsTitle = { color:'9F9F9F', marginPt:3, border:[0,0,{pt:'1',color:'CFCFCF'},0] }; pptx.setLayout({ name:'A3', width:16.5, height:11.7 }); slide.slideNumber({ x:0.5, y:'90%' }); slide.addTable( [ [{ text:'Simple Example', options:optsTitle }] ], { x:0.5, y:0.13, w:12.5 } ); //slide.addText('Hello World!', { x:0.5, y:0.7, w:6, h:1, color:'0000FF' }); slide.addText('Hello 45! ', { x:0.5, y:0.5, w:6, h:1, fontSize:36, color:'0000FF', shadow:{type:'outer', color:'00AAFF', blur:2, offset:10, angle: 45, opacity:0.25} }); slide.addText('Hello 180!', { x:0.5, y:1.0, w:6, h:1, fontSize:36, color:'0000FF', shadow:{type:'outer', color:'ceAA00', blur:2, offset:10, angle:180, opacity:0.5} }); slide.addText('Hello 355!', { x:0.5, y:1.5, w:6, h:1, fontSize:36, color:'0000FF', shadow:{type:'outer', color:'aaAA33', blur:2, offset:10, angle:355, opacity:0.75} }); // Bullet Test: Number slide.addText(999, { x:0.5, y:2.0, w:'50%', h:1, color:'0000DE', bullet:true }); // Bullet Test: Text test slide.addText('Bullet text', { x:0.5, y:2.5, w:'50%', h:1, color:'00AA00', bullet:true }); // Bullet Test: Multi-line text test slide.addText('Line 1\nLine 2\nLine 3', { x:0.5, y:3.5, w:'50%', h:1, color:'AACD00', bullet:true }); // Table cell margin:0 slide.addTable( [['margin:0']], { x:0.5, y:1.1, margin:0, w:0.75, fill:'FFFCCC' } ); // Fine-grained Formatting/word-level/line-level Formatting slide.addText( [ { text:'right line', options:{ fontSize:24, fontFace:'Courier New', color:'99ABCC', align:'r', breakLine:true } }, { text:'ctr line', options:{ fontSize:36, fontFace:'Arial', color:'FFFF00', align:'c', breakLine:true } }, { text:'left line', options:{ fontSize:48, fontFace:'Verdana', color:'0088CC', align:'l' } } ], { x:0.5, y:3.0, w:8.5, h:4, margin:0.1, fill:'232323' } ); // Export: pptx.save('Sample Presentation'); } /* The "Text" demo on the PptxGenJS homepage - codified here so we can quickly reproduce the screencaps, etc. as needed */ function doHomepageDemo_Text() { var pptx = new PptxGenJS(); pptx.setLayout('LAYOUT_WIDE'); var slide = pptx.addNewSlide(); slide.addText( 'BONJOUR - CIAO - GUTEN TAG - HELLO - HOLA - \nNAMASTE - OLÀ - ZDRAS-TVUY-TE - こんにちは - 你好', { x:0.0, y:0.0, w:'100%', h:1.25, align:'c', fontSize:18, color:'0088CC', fill:'F1F1F1' } ); slide.addText("Line-Level Formatting:", { x:0.5, y:1.5, w:'40%', h:0.38, color:'0088CC' }); slide.addText( [ { text:'1st line', options:{ fontSize:24, fontFace:'Courier New', color:'99ABCC', align:'r', breakLine:true } }, { text:'2nd line', options:{ fontSize:36, fontFace:'Arial', color:'FFFF00', align:'c', breakLine:true } }, { text:'3rd line', options:{ fontSize:48, fontFace:'Verdana', color:'0088CC', align:'l' } } ], { x:0.5, y:2.0, w:6, h:2.25, margin:0.1, fill:'232323' } ); slide.addText("Bullets: Normal", { x:8.0, y:1.5, w:'40%', h:0.38, color:'0088CC' }); slide.addText( 'Line 1\nLine 2\nLine 3', { x:8.0, y:2.0, w:'30%', h:1, color:'393939', fontSize:16, fill:'F2F2F2', bullet:true } ); slide.addText("Bullets: Numbered", { x:8.0, y:3.4, w:'40%', h:0.38, color:'0088CC' }); slide.addText( 'Line 1\nLine 2\nLine 3', { x:8.0, y:3.9, w:'30%', h:1, color:'393939', fontSize:16, fill:'F2F2F2', bullet:{type:'number'} } ); slide.addText("Bullets: Custom", { x:8.0, y:5.3, w:'40%', h:0.38, color:'0088CC' }); slide.addText('Star bullet! ', { x:8.0, y:5.6, w:'40%', h:0.38, color:'CC0000', bullet:{code:'2605'} }); slide.addText('Check bullet!', { x:8.0, y:5.9, w:'40%', h:0.38, color:'00CD00', bullet:{code:'2713'} }); var shadowOpts = { type:'outer', color:'696969', blur:3, offset:10, angle:45, opacity:0.8 }; slide.addText("Text Shadow:", { x:0.5, y:6.0, w:'40%', h:0.38, color:'0088CC' }); slide.addText( 'Outer Shadow (blur:3, offset:10, angle:45, opacity:80%)', { x:0.5, y:6.4, w:12, h:0.6, fontSize:32, color:'0088cc', shadow:shadowOpts } ); pptx.save('Demo-Text'); } function doTablePagingLogicCheck() { var pptx = new PptxGenJS(); var slide = pptx.addNewSlide(); slide.addText('Table Paging Logic Check', { x:0.0, y:'90%', w:'100%', align:'c', fontSize:18, color:'0088CC', fill:'F2F9FC' }); var numMargin = 1.25; slide.addShape(pptx.shapes.RECTANGLE, { x:0.0, y:0.0, w:numMargin, h:numMargin, fill:'FFFCCC' }); slide.addTable( ['short','table','whatever'], {x:numMargin, y:numMargin, margin:numMargin, colW:2.5, fill:'F1F1F1'} ); pptx.save('PptxGenJs-TablePagingLogicCheck'); } function buildDataTable() { // STEP 1: $('#tabAutoPaging tbody').empty(); // STEP 2: for (var idx=0; idx<$('#numTab2SlideRows').val(); idx++) { var strHtml = '<tr>' + '<td style="text-align:center">' + (idx+1) + '</td>' + '<td>' + gArrNamesL[ Math.floor(Math.random()*10) ] + '</td>' + '<td>' + gArrNamesF[ Math.floor(Math.random()*10) ] + '</td>' + '<td>Text:<br>' + gStrLoremIpsum.substring( 0, (Math.floor(Math.random()*10)+2)*130 ) + '</td>' + '</tr>'; $('#tabAutoPaging tbody').append( strHtml ); } // STEP 3: Add some style to table for testing // TEST Padding $('#tabAutoPaging thead th').css('padding','10px 5px'); // TEST font-size/auto-paging $('#tabAutoPaging tbody tr:first-child td:last-child').css('font-size','12px'); $('#tabAutoPaging tbody tr:last-child td:last-child').css('font-size','16px'); } function table2slidesDemoForTab(inTabId,inOpts) { var pptx = new PptxGenJS(); pptx.addSlidesForTable(inTabId,(inOpts||null)); pptx.save( inTabId+'_'+getTimestamp() ); } function table2slidesBullets() { var pptx = new PptxGenJS(); pptx.addSlidesForTable('tableWithBullets'); pptx.save( 'tabBullets_'+getTimestamp() ); } /* DESC: Test for backward compatibility with Slide Masters defined in `pptxgen.masters.js` */ function testOnly_LegacyMasterSlides() { // TEST-ONLY: DO NOT USE/COPY ME!! var pptx = new PptxGenJS(); pptx.setLayout('LAYOUT_WIDE'); var slide = pptx.addNewSlide( pptx.masters.TITLE_SLIDE ); pptx.save('Demo-LegacyMasterSlides_'+getTimestamp()); } // Table-to-Slides Demos ======================================================================= function addMasterDefs(pptx) { // 1: pptx.defineSlideMaster({ title: 'TITLE_SLIDE', bkgd: { data:BKGD_STARLABS }, objects: [ { 'line': { x: 3.5, y:1.00, w:6.00, line:'0088CC', line_size:5 } }, //{ 'chart': { type:'PIE', data:[{labels:['R','G','B'], values:[10,10,5]}], opts:{x:0.25, y:0.25, w:3, h:3} } }, { 'rect': { x: 0.0, y:5.30, w:'100%', h:0.75, fill:'F1F1F1' } }, { 'text': { text:'Global IT & Services :: Status Report', options:{ x:3.0, y:5.30, w:5.5, h:0.75, fontFace:'Arial', color:'363636', fontSize:20, valign:'m', margin:0 } } }, { 'image': { x:11.3, y:6.40, w:1.67, h:0.75, data:starlabsLogoSml } } ] }); // 2: pptx.defineSlideMaster({ title: 'MASTER_SLIDE', bkgd: 'EEEEEE', slideNumber: { x:1.0, y:7.0, color:'FFFFFF' }, margin: [ 0.5, 0.25, 1.25, 0.25 ], objects: [ { 'rect': { x:0, y:6.9, w:'100%', h:0.6, fill:'003b75' } }, { 'text': { text:'S.T.A.R. Laboratories', options:{x:0, y:6.9, w:'100%', h:0.6, align:'c', valign:'m', color:'FFFFFF', fontSize:12} } } ] }); // 3: pptx.defineSlideMaster({ title: 'THANKS_SLIDE', bkgd: '36ABFF', objects: [ { 'rect': { x:0.0, y:3.4, w:'100%', h:2.0, fill:'ffffff' } }, { 'text': { text:'Thank You!', options:{ x:0.0, y:0.9, w:'100%', h:1, fontFace:'Arial', color:'FFFFFF', fontSize:60, align:'c' } } }, { 'image': { x:4.6, y:3.5, w:4, h:1.8, data:LOGO_STARLABS } } ] }); } function table2slides1() { // FIRST: Instantiate new PptxGenJS instance var pptx = new PptxGenJS(); // STEP 1: Add Master Slide defs / Set slide size/layout addMasterDefs(pptx); pptx.setLayout('LAYOUT_WIDE'); // STEP 2: Set generated Slide options var objOpts = {}; //objOpts.debug = true; // DEBUG: if ( $('#selSlideMaster').val() ) objOpts.master = $('#selSlideMaster').val(); if ( $('input[name=radioHead]:checked').val() == "Y" ) objOpts.addHeaderToEach = true; if ( $('#checkStartY').prop('checked') ) objOpts.newPageStartY = Number($('#numTab2SlideStartY').val()); // STEP 3: Pass table to addSlidesForTable function to produce 1-N slides pptx.addSlidesForTable('tabAutoPaging', objOpts); // LAST: Export Presentation pptx.save('Demo-TableToSlidesMasterSlide_'+getTimestamp()); } function table2slides2() { // FIRST: Instantiate new PptxGenJS instance var pptx = new PptxGenJS(); // STEP 1: Add Master Slide defs / Set slide size/layout addMasterDefs(pptx); pptx.setLayout('LAYOUT_WIDE'); // STEP 2: Set generated Slide options var objOpts = {}; //objOpts.debug = true; if ( $('#selSlideMaster').val() ) objOpts.master = $('#selSlideMaster').val(); if ( $('input[name=radioHead]:checked').val() == "Y" ) objOpts.addHeaderToEach = true; if ( $('#checkStartY') ) objOpts.newPageStartY = Number($('#numTab2SlideStartY').val()); // STEP 3: Add a custom shape (text in this case) to each Slide // EXAMPLE: Add any dynamic content to each generated Slide // DESC: Add something you cant predefine in a master - like a username/timestamp for each slide, etc. // NOTE: You can do this for all other types as well: .addShape(), .addTable() and .addImage() objOpts.addText = { text:"(dynamic content - ex:user/datestamp)", options:{ x:1.1, y:0.6, color:'0088CC', fontFace:'Arial', fontSize:12 } }; // STEP 4: Pass table to addSlidesForTable function to produce 1-N slides pptx.addSlidesForTable('tabAutoPaging', objOpts); // LAST: Export Presentation pptx.save('Table2Slides-with-dynamic-text'); } // ================================================================================================================== $(document).ready(function(){ // REALITY-CHECK: Ensure user has a modern browser if ( !window.Blob ) { alert("Unsupported Browser\n\nSorry, but you'll need a modern browser - (Chrome, Firefox, Edge, Opera) or IE11 - to enable this feature."); return; } else if ( typeof PptxGenJS === 'undefined' ) { alert("Oops!\n\n`PptxGenJS` is undefined - maybe a bad link to the 'pptxgen.js' file or something...?\n"); return; } /* FIXME: Abadoned: jquery cant parse `pptxgenjs-demo.js` for some reason... // If you're me: Load newest/local copy for dev/test work :-) if ( window.location.href.toLowerCase().indexOf('gitbrent') > -1 ) { // Dynamically load library as SharePoint Online is *BAD* about caching $.getScript("../SiteAssets/pptxgenjs/dist/pptxgen.js", function(){ console.log('DEBUG: local file loaded: `dist/pptxgen.js`'); $.getScript("../SiteAssets/pptxgenjs/examples/pptxgenjs-demo.js", function(){ console.log('DEBUG: local file loaded: `examples/pptxgenjs-demo.js`'); }) .fail(function(err){ console.error(err.statusText); console.log(err); }); }); } */ // STEP 1: Set UI (if you're me) if ( window.location.href.indexOf('brentely') > 0 ) { $('#tab1sec1').click(); $('#tab1sec2').click(); } // STEP 2: Build UI elements buildDataTable(); var pptx = new PptxGenJS(); ['MASTER_SLIDE','THANKS_SLIDE','TITLE_SLIDE'].forEach(function(name,idx){ $('#selSlideMaster').append('<option value="'+ name +'">'+ name +'</option>'); }); // STEP 3: Populate code areas $('#demo-basic').html('<pre class="prettyprint">\n' + '// STEP 1: Create a new Presentation\n' + 'var pptx = new PptxGenJS();\n' + '\n' + '// STEP 2: Add a new Slide to the Presentation\n' + 'var slide = pptx.addNewSlide();\n' + '\n' + '// STEP 3: Add any objects to the Slide (charts, tables, shapes, images, etc.)\n' + "slide.addText(\n" + " 'BONJOUR - CIAO - GUTEN TAG - HELLO - HOLA - NAMASTE - OLÀ - ZDRAS-TVUY-TE - こんにちは - 你好',\n" + " { x:0.0, y:0.25, w:'100%', h:1.5, align:'c', fontSize:24, color:'0088CC', fill:'F1F1F1' }\n" + ");\n" + '\n' + '// STEP 4: Send the PPTX Presentation to the user, using your choice of file name\n' + "pptx.save('PptxGenJs-Basic-Slide-Demo');\n" + '</pre>\n'); $('#demo-youtube').html('<pre class="prettyprint">\n' + "var pptx = new PptxGenJS();\n" + "var slide = pptx.addNewSlide();\n" + '\n' + "// Provide the usual options (locations and size), then pass the embed code from YouTube (it's on every video page)\n" + "slide.addText('TED Talks 2016: Top 10', { x:0.5, y:0.2, w:8.00, h:0.4, color:'0088CC' });\n" + "slide.addMedia({ type:'online', link:'https://www.youtube.com/embed/Dph6ynRVyUc', x:0.5, y:0.6, w:8.00, h:4.54 });\n" + '\n' + "pptx.save('PptxGenJs-YouTube-Demo');\n" + '</pre>\n'); $('#demo-sandbox').html('<pre class="prettyprint" style="margin:0 !important; width:auto; padding:10px; border-radius:0;">\n' + "var pptx = new PptxGenJS();\n" + "pptx.setLayout('LAYOUT_WIDE');\n" + "var slide = pptx.addNewSlide();\n" + "\n" + "// Bullets with indent levels\n" + "slide.addText(\n" + " [\n" + " { text:'1st line', options:{ fontSize:24, bullet:true, color:'99ABCC' } },\n" + " { text:'2nd line', options:{ fontSize:36, bullet:true, color:'FFFF00', indentLevel:1 } },\n" + " { text:'3rd line', options:{ fontSize:48, bullet:true, color:'0088CC', indentLevel:2 } }\n" + " ],\n" + " { x:1.5, y:1.5, w:6, h:2, margin:0.1, fill:'232323' }\n" + ");\n" + "\n" + "pptx.save('PptxGenJS-Sandbox_'+getTimestamp());\n" + "</pre>\n" ); // STEP 4: Show library info { if ( typeof Promise !== 'function' ) { $('#pptxVersion').after('<div style="color:red">Promise undefined! (IE11 requires promise.js)<div>'); } else { // NOTE: Tooltips (span title below) only works with quote (not single quote) var pptx = new PptxGenJS(); $('#infoBar').append('<div style="flex:2 0 auto; color:#66A7F7"><div class="iconSvg size24 info"></div>Library Version: <span>'+pptx.version+'</span></div>'); $('#infoBar').append("<div style='flex:1 0 auto; text-align:right;'><span style='cursor:help' title='"+ JSON.stringify(pptx.charts) +"'><div class='iconSvg size24 circle check'></div>pptx.charts = "+ Object.keys(pptx.charts).length +"</span></div>"); $('#infoBar').append("<div style='flex:1 0 auto; text-align:right;'><span style='cursor:help' title='"+ JSON.stringify(pptx.colors) +"'><div class='iconSvg size24 circle check'></div>pptx.colors = "+ Object.keys(pptx.colors).length +"</span></div>"); $('#infoBar').append('<div style="flex:1 0 auto; text-align:right;"><span><div class="iconSvg size24 circle check"></div>pptx.shapes = '+ Object.keys(pptx.shapes).length +'</span></div>'); } } // STEP 5: Demo setup $('#tabCellLotsoText').text( gStrLoremIpsum.substring(0,3000) ); // LAST: Nav across sessions doNavRestore(); }); </script> <!-- Add source highlighting once script above populates code everywhere --> <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=sunburst"></script> </head> <body> <div data="anchors"> <a href="#tab1"></a><a href="#tab2"></a><a href="#tab3"></a><a href="#tab4"></a><a href="#tab5"></a><a href="#tab6"></a><a href="#tab7"></a> </div> <div id="contBody"> <div id="contTitle" class="table"> <div> <div class="bigTitle"> <a href="https://github.com/GitBrent/PptxGenJS" target="_blank" title="GitHub Project Page">PptxGenJS</a> </div> <div class="subTitle"> JavaScript PowerPoint Generation Library :: Presentation Demos </div> </div> <div style="vertical-align:middle;"> <div id="contBtns" class="flex"> <div style="flex:2 0 auto"> <button id="btnRun" type="button" class="flatBtn shadow flatBtn-blueMd" onclick="runEveryTest()">Run All Demos</button> </div> <div style="flex:1 0 auto"> <button id="btnGit" type="button" class="flatBtn small flatBtn-nsOrange" onclick="window.open('https://github.com/gitbrent/PptxGenJS')">GitHub Site</button> </div> <div style="flex:1 0 auto; text-align:right;"> <button id="btnDoc" type="button" class="flatBtn small flatBtn-nsPurple" onclick="window.open('https://gitbrent.github.io/PptxGenJS/docs/installation.html')">View Documentation</button> </div> </div> </div> </div> <div id="navTabs" class="modernTabs"> <ul> <li id="nav1" class="active" onclick="doNav(1)">Introduction</li> <li id="nav2" onclick="doNav(2)">HTML to PPTX</li> <li id="nav3" onclick="doNav(3)">Charts</li> <li id="nav4" onclick="doNav(4)">Images &amp; Media</li> <li id="nav5" onclick="doNav(5)">Shapes &amp; Text</li> <li id="nav6" onclick="doNav(6)">Tables</li> <li id="nav7" onclick="doNav(7)">Templates</li> </ul> <div id="tab1" class="active" data-title="Intro"> <div id="infoBar" class="flex"></div> <div id="tab1sec1" class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow active"></div>Basic Presentation: Slide </div> <div class="sectionBox" style="display:block; padding:15px;"> <div id="demo-basic" class="code" style="text-align:left; margin-bottom:15px"></div> <div style="text-align:center; padding:20px;"> <input type="button" class="flatBtn flatBtn-green" value="Basic Slide Demo" onclick="eval( $('#demo-basic').text() )"> </div> </div> <div id="tab1sec2" class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow"></div>Code Sandbox </div> <div class="sectionBox" style="display:none"> <div class="highlightBox"> Code below is editable - Test snippets of code from the demos/readme! </div> <div class="code" style="text-align:left; margin-bottom:15px"> <div id="demo-sandbox" contenteditable="true" style="background:#f1f1f1;"></div> </div> <div style="text-align:center; padding:20px;"> <input type="button" class="flatBtn flatBtn-nsOrange" value="Execute Sandbox Code" onclick="eval( $('#demo-sandbox').text() )"> </div> </div> </div> <div id="tab2" data-title="HTML to PowerPoint"> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> HTML to PowerPoint </div> <div style="font-size:120%; color:#696969;"> Reproduces an HTML table into 1 or more slides (auto-paging) using the syntax <div class="codeSnip">pptx.addSlidesForTable('tableId');</div> <ul> <li>Supported cell styling includes background colors, borders, fonts, padding, etc.</li> <li>Slide margin settings can be set using options, or by providing a Master Slide definition</li> <li>View the <a href="https://gitbrent.github.io/PptxGenJS/docs/html-to-powerpoint.html">HTML to PowerPoint documentation</a> for full details and examples</li> </ul> Notes: <ul> <li>CSS styles are only supported down to the cell level (word-level formatting is not supported)</li> <li>Nested tables are not supported in PowerPoint, therefore they cannot be reproduced (only the text will be included)</li> </ul> </div> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow active"></div>Basic Functionality and Options </div> <div class="sectionBox"> <div id="contAutoPagingOptions" class="sectionCont" style="flex-wrap:nowrap"> <fieldset> <legend>Demo Table</legend> <div class="tableRows" style="margin:0 0 10px 10px"> <div> <div><label for="numTab2SlideRows">Number of Table Rows:</label></div> <div><input id="numTab2SlideRows" type="number" min="1" max="25" value="3" onchange="buildDataTable()"></div> </div> <div> <div><label for="numTab2Padding">Cell Padding (points):</label></div> <div><input id="numTab2Padding" type="number" min="0" max="25" value="5" onchange="$('#tabAutoPaging th, #tabAutoPaging td').css('padding',$('#numTab2Padding').val()+'px')"></div> </div> </div> </fieldset> <fieldset> <legend><a href="https://gitbrent.github.io/PptxGenJS/docs/html-to-powerpoint.html#html-to-powerpoint-options" title="View Docs"><div class="iconSvg size24 lightbulb"></div></a>Options: Auto-Paging</legend> <div class="tableRows" style="margin:0 0 10px 10px"> <div> <div> <div class="codeSnip">addHeaderToEach</div> </div> <div> Show Table Header on Each Slide? </div> <div> <label style="white-space:nowrap"><input type="radio" name="radioHead" value="Y" checked="checked">Yes</label> <label style="white-space:nowrap"><input type="radio" name="radioHead" value="N">No</label> </div> </div> <div> <div> <div class="codeSnip">newPageStartY</div> </div> <div> <label for="numTab2SlideStartY">Y location for table on subsequent slides</label> </div> <div style="white-space:nowrap"> <label for="checkStartY" style="margin-right:3px"><input id="checkStartY" type="checkbox" onclick="$('#contStartY').toggle()">Enable?</label> <span id="contStartY" style="display:none"><input id="numTab2SlideStartY" type="number" min="0" max="10" step="0.5" value="1.5"></span> </div> </div> </div> </fieldset> <fieldset> <legend><a href="https://gitbrent.github.io/PptxGenJS/docs/masters.html" title="View Docs"><div class="iconSvg size24 lightbulb"></div></a>Option: Master</legend> <div class="tableRows" style="margin:0 0 10px 10px"> <div> <div>Master Name:</div> <div><select id="selSlideMaster"><option selected="selected">(None)</option></select></div> </div> </div> </fieldset> </div> <table id="tabAutoPaging" class="tabCool"> <thead> <tr> <th data-pptx-min-width="0.6" style="width:5%">Row</th> <th data-pptx-min-width="0.8" style="width:10%">Last Name</th> <th data-pptx-min-width="0.8" style="width:10%">First Name</th> <th style="width:75%; border-right:1px solid rgba(0,255,0,0.7);">Description</th> </tr> </thead> <tbody></tbody> </table> <div id="contAutoPagingBtns" style="text-align:center; padding:20px 20px 0 20px;"> <button type="button" class="flatBtn flatBtn-nsBlue" onclick="table2slides1()">Demo Table Above</button> <button type="button" class="flatBtn flatBtn-nsOrange" onclick="table2slides2()">Demo Table Above (add dynamic text)</button> </div> </div> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow"></div>Table Styles </div> <div id="html2PptxTabs-styles" class="sectionBox" style="display:none"> <div class="sectionCont"> <fieldset class="demoFset"> <legend>Plain/Unstyled Table</legend> <table id="tabNoStyle"> <thead> <tr> <th>Name</th> <th>Email</th> <th>Company</th> <th>Feedback</th> </tr> </thead> <tbody> <tr> <td>Elon Musk</td> <td>Elon@tesla.com</td> <td>Tesla Motors &amp; SpaceX</td> <td>PptxGenJS is almost as good as rockets that can land themselves</td> </tr> <tr> <td>Tim Cook</td> <td>tim@apple.com</td> <td>Apple Inc.</td> <td>Jony Ive said the Keynote team needs to hire you</td> </tr> <tr> <td>Satya Nadella</td> <td>ceo@microsoft.com</td> <td>Microsoft Inc.</td> <td>The PowerPoint team needs to hire you</td> </tr> </tbody> </table> <div class="demoBtns"> <button type="button" class="flatBtn flatBtn-green" onclick="table2slidesDemoForTab('tabNoStyle')">Table-to-Slides Demo</button> </div> </fieldset> <fieldset class="demoFset"> <legend>Inherited Style</legend> <table id="tabInheritStyle" class="tabHtmlToPpt" cellspacing="0" cellpadding="3"> <thead> <tr> <th>Company</th> <th>Contact</th> <th>Feedback</th> </tr> </thead> <tbody> <tr> <td>Tesla &amp; SpaceX</td> <td>Elon@tesla.com</td> <td>PptxGenJS is almost as good as rockets that can land themselves</td> </tr> <tr> <td>Apple Inc.</td> <td>tim@apple.com</td> <td>Jony Ive said the Keynote team needs to hire you</td> </tr> <tr> <td>Microsoft Inc.</td> <td>ceo@microsoft.com</td> <td>The PowerPoint team needs to hire you</td> </tr> </tbody> </table> <div class="demoBtns"> <button type="button" class="flatBtn flatBtn-green" onclick="table2slidesDemoForTab('tabInheritStyle')">Table-to-Slides Demo</button> </div> </fieldset> </div> </div> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow"></div>Rowspans/Colspans </div> <div id="html2PptxTabs-spans" class="sectionBox" style="display:none"> <div class="sectionCont"> <fieldset class="demoFset"> <legend>Colspan</legend> <table id="tabColspan" class="tabHtmlToPpt"> <thead> <tr> <th class="tg-header">First Name</th> <th class="tg-header">Last Name</th> <th class="tg-header" colspan="2">Colspan Column</th> </tr> </thead> <tbody> <tr> <td>Jill</td> <td>Smith</td> <td>59</td> </tr> <tr> <td>Eve</td> <td>Pilgrim</td> <td>94</td> </tr> <tr> <td>Scott</td> <td>Jackson</td> <td>101</td> </tr> </tbody> </table> <div class="demoBtns"> <button type="button" class="flatBtn flatBtn-green" onclick="table2slidesDemoForTab('tabColspan')">Colspan Demo</button> </div> </fieldset> <fieldset class="demoFset"> <legend>Rowspan</legend> <table id="tabRowspan" class="tabHtmlToPpt"> <thead> <tr> <th class="tg-header">Last Name</th> <th class="tg-header">First Name</th> <th class="tg-header">Count</th> </tr> </thead> <tbody> <tr> <td rowspan="3">Smith</td> <td>Liz</td> <td>50</td> </tr> <tr> <td>Eve</td> <td>94</td> </tr> <tr> <td>Scott</td> <td>101</td> </tr> </tbody> </table> <div class="demoBtns"> <button type="button" class="flatBtn flatBtn-green" onclick="table2slidesDemoForTab('tabRowspan')">Rowspan Demo</button> </div> </fieldset> <fieldset class="demoFset"> <legend>Rowspan plus Colspan</legend> <table id="tabRowColspan" class="tabHtmlToPpt"> <thead> <tr> <th class="tg-header" colspan="2">Name</th> <th class="tg-header" rowspan="2">Count</th> </tr> <tr> <th class="tg-header">Last</th> <th class="tg-header">First</th> </tr> </thead> <tbody> <tr> <td>Smith</td> <td>Liz</td> <td>50</td> </tr> <tr> <td>Eve</td> <td>Williams</td> <td>94</td> </tr> </tbody> </table> <div class="demoBtns"> <button type="button" class="flatBtn flatBtn-green" onclick="table2slidesDemoForTab('tabRowColspan',{addHeaderToEach:true})">Rowspan+Colspan Demo</button> <!-- DEBUG <button type="button" class="flatBtn flatBtn-blueMd" onclick="$('#tabRowColspan tbody').append($('#tabRowColspan tbody tr:first-child').clone())">Add Table Row</button>--> </div> </fieldset> </div> </div> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow"></div>Auto-Paging </div> <div id="html2PptxTabs-spans" class="sectionBox" style="display:none"> <div class="sectionCont"> <fieldset class="demoFset"> <legend>Scenario: One cell with large amount of text</legend> <table id="tabLotsoText" class="tabHtmlToPpt"> <thead> <tr> <th class="tg-header">Executive Status</th> </tr> </thead> <tbody> <tr> <td id="tabCellLotsoText">99</td> </tr> </tbody> </table> <div class="demoBtns"> <button type="button" class="flatBtn flatBtn-green" onclick="table2slidesDemoForTab('tabLotsoText',{'addHeaderToEach':true})">Lots-o-Text Demo</button> </div> </fieldset> </div> </div> <!-- FUTURE: <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow active"></div>Table With Bullets </div> <div class="sectionBox"> <table id="tableWithBullets" style="width:50%; font-family:Arial;"> <tbody> <tr> <td style="border:1px solid #c7c7c7; background:white; text-align:left;"> <ul> <li><b>Bold Text</b></li> <ol> <li>Nested</li> <li>Nested</li> <li>Nested</li> </ol> <li><u>Underline Text</u></li> </ul> </td> <td style="border:1px solid #c7c7c7; background:white; text-align:left;"> <ul> <li>Level 1 <ul> <li>Level 2 <ul> <li><a href="https://google.com">Level 3 Link</a></li> <li><a href="https://amazon.com">Level 3 Link</a></li> </ul> </li> </ul> </li> </ul> </td> </tr> </tbody> </table> <div style="text-align:center; padding:20px;"> <input type="button" class="flatBtn flatBtn-nsBlue" onclick="table2slidesBullets()" value="Bullet Table Demo"> </div> </div> --> </div> <div id="tab3" data-title="Charts"> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow active"></div>Charts </div> <div class="sectionBox"> <div class="sectionCont"> <fieldset> <legend>Bar Chart</legend> <h3>Slide 1</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Vertical/Horizontal bars</div> <h3>Slide 2</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Grid/Axis options</div> <h3>Slide 3</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Stacked/PercentStacked Bars</div> <h3>Slide 4</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Lots of Bars</div> <h3>Slide 5</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Bar colors, majorUnit, Number Format</div> </fieldset> <fieldset> <legend>Tornado Chart</legend> <h3>Slide 6</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Tornado Type</div> </fieldset> <fieldset> <legend>Line Chart</legend> <h3>Slide 7</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Line Smoothing,<br>Shadow,<br>Size,<br>Symbol Size</div> <h3>Slide 8</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>lineDataSymbol,<br>SymbolSize</div> <h3>Slide 9</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Lots of Categories</div> </fieldset> <fieldset> <legend>Area Chart</legend> <h3>Slide 10</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Opacity and other options</div> </fieldset> <fieldset> <legend>Pie Chart</legend> <h3>Slide 11</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Various options</div> <h3>Slide 12</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Doughnut Type</div> </fieldset> <fieldset> <legend>X Y (Scatter) Chart</legend> <h3>Slide 13</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Various Options</div> </fieldset> <fieldset> <legend>Bubble Chart</legend> <h3>Slide 14</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Various Options</div> </fieldset> <fieldset> <legend>Radar Chart</legend> <h3>Slide 15</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Various Options</div> </fieldset> <fieldset> <legend>Multi-Type Charts</legend> <h3>Slide 16</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Various Mixed Chart Types</div> </fieldset> <fieldset> <legend>Chart Options</legend> <h3>Slide 17</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Shadows and Transparent Color</div> </fieldset> </div> <div> <input type="button" class="flatBtn flatBtn-green" value="Generate Demo Presentation" onclick="execGenSlidesFuncs('Chart')"> </div> </div> </div> <div id="tab4" data-title="Images/Media"> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow active"></div>Images &amp; Media </div> <div> <div class="sectionBox"> <div class="sectionCont"> <fieldset> <legend>Images: Various Types</legend> <h3>Slide 1</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Animated GIF (shows in Presenation mode)</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Images from local and remote CDN URLs</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Pre-encoded images (using `data:[base64]`)</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Images with hyperlinks/tooltips</div> </fieldset> <fieldset> <legend>Images: Sizing and Rounding</legend> <h3>Slide 2</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Image Rounding</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Sizing: Contain</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Sizing: Cover</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Sizing: Crop</div> </fieldset> </div> <div class="sectionCont"> <fieldset> <legend>Media: Video</legend> <h3>Slide 3</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Various formats&nbsp;&nbsp; <span style="color:red; background:#fffccc;">(most OS's wont have every format codec - YMMV)</span> </div> <div class="chkRow"><div class="iconSvg size16 yes"></div>YouTube&nbsp;&nbsp; <span style="color:red; background:#fffccc;">(only supported in PowerPoint Online)</span> </div> <div class="chkRow"> <div style="margin-left:20px"><input id="chkYoutube" type="checkbox"><label for="chkYoutube">Include YouTube demo?</label></div> <div style="margin-left:20px; color:#d7d7d7;">(open in PowerPoint Online or a content warning will show in desktop app)</div> </div> </fieldset> <fieldset> <legend>Media: Audio</legend> <h3>Slide 4</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Misc Audio formats (mp3, wav)</div> </fieldset> </div> <div> <input type="button" class="flatBtn flatBtn-green" style="margin-right:10px !important" value="Generate Demo: Images" onclick="execGenSlidesFuncs(['Image'])"> <input type="button" class="flatBtn flatBtn-green" style="margin-right:10px !important" value="Generate Demo: Media" onclick="execGenSlidesFuncs(['Media'])"> <input type="button" class="flatBtn flatBtn-blueMd" value="Generate Demo: Images and Media" onclick="execGenSlidesFuncs(['Image','Media'])"> </div> </div> </div> </div> <div id="tab5" data-title="Shapes/Text"> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow active"></div>Shapes &amp; Text </div> <div class="sectionBox"> <div class="sectionCont"> <fieldset> <legend>Shape Objects</legend> <h3>Slide 1</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Shapes: Rectangle, Line, Oval, Triangle</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Shapes: Flipped, With and Without Text</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Shape Borders</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Lines: With and Without Arrowheads</div> <h3>Slide 2</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Same Shapes with Text</div> </fieldset> <fieldset> <legend>Text Objects</legend> <h3>Slide 3</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Word-Level Formatting</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Multi-Line Text</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Hyperlinks, Text Shadow, Text Outline</div> <h3>Slide 4</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Bullets: Regular and Custom</div> <h3>Slide 5</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Text alignment, percent x/y, etc</div> <h3>Slide 6</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Scheme Colors</div> </fieldset> </div> <div> <input type="button" class="flatBtn flatBtn-green" value="Generate Demo Presentation" onclick="execGenSlidesFuncs(['Shape','Text'])"> </div> </div> </div> <div id="tab6" data-title="Tables"> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow active"></div>Tables </div> <div class="sectionBox"> <div class="sectionCont"> <fieldset> <legend>Table Layout/Format</legend> <h3>Slide 1</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Text Alignment</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Cell Styles</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Row Height / Col Width</div> <h3>Slide 2</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Colspans/Rowspans</div> <h3>Slide 3</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Extreme Colspans/Rowspans</div> </fieldset> <fieldset style="height:auto"> <legend>Cell Formatting</legend> <h3>Slide 4</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Cell Margins</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Complex Cell Borders</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Escaped Special Characters</div> <h3>Slide 5</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Cell Text Formatting Overview</div> <h3>Slide 6</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Cell Text Formatting Examples 2</div> </fieldset> <fieldset style="height:auto"> <legend>Table Auto-Paging</legend> <h3>Slide 7-n</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>Test basic functionality</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Test with small table dimensions</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Test with correct starting `{y:4.0}`</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Test with `{ newPageStartY:0.5 }`</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Test with `{ autoPage:false }`</div> <div class="chkRow"><div class="iconSvg size16 yes"></div>Three Tables with various `lineWeight`</div> </fieldset> </div> <div> <input type="button" class="flatBtn flatBtn-green" value="Generate Demo Presentation" onclick="execGenSlidesFuncs('Table')"> </div> </div> </div> <div id="tab7" data-title="Templates/Master Slides"> <div class="sectionTitle" style="cursor:pointer" title="Click to Show/Hide" onclick="$(this).next('div').toggle('slow'); $(this).find('.arrow').toggleClass('active');"> <div class="arrow active"></div>Slide Masters / Templates / Layouts </div> <div class="sectionBox"> <div class="sectionCont"> <fieldset> <legend>Misc Tests</legend> <h3>Slide 1</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>TITLE_SLIDE</div> <h3>Slide 2</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>MASTER_SLIDE</div> <h3>Slide 3</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>MASTER_SLIDE</div> <h3>Slide 4</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>MASTER_SLIDE</div> <h3>Slide 5</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>MASTER_SLIDE</div> <h3>Slide 6</h3> <div class="chkRow"><div class="iconSvg size16 yes"></div>THANKS_SLIDE</div> </fieldset> <fieldset> <legend>Example</legend> <h3>Creating Slide Masters is easy!</h3> <p></p> <div style="margin-left:10px"> <code>pptx.defineSlideMaster({</code> <code> title : 'MASTER_SLIDE',</code> <code> margin: [0.5, 0.25, 1.00, 0.25],</code> <code> bkgd : 'FFFFFF',</code> <code> objects: [</code> <code> {rect: { x:0, y:6.9, w:'100%', h:0.6, fill:'003b75' }},</code> <code> {image: { x:11.45, y:5.95, w:1.67, h:0.75, data:starlabsLogoSml }},</code> <code> {text: {</code> <code> text:'S.T.A.R. Laboratories - Confidential',</code> <code> options:{x:0, y:6.9, w:'100%', align:'c', color:'FFFFFF', fontSize:12}</code> <code> }},</code> <code> {placeholder: { options:{ name:'title', type:'title', x:0.5, y:0.2, w:12, h:1.0 }, text:'' }}</code> <code> {placeholder: { options:{ name:'body', type:'body', x:6.0, y:1.5, w:12, h:5.25 }, text:'' }}</code> <code> ],</code> <code> slideNumber: { x:1.0, y:7.0, color:'FFFFFF' }</code> <code>});</code> </div> </fieldset> </div> <div> <input type="button" class="flatBtn flatBtn-green" value="Generate Demo Presentation" onclick="execGenSlidesFuncs('Master')"> </div> </div> </div> </div> </div> </body> </html>