From 19a69e2c39d91f56eefaf2e6cb0ec1888c972b04 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sat, 12 Apr 2014 10:12:24 +0700 Subject: [PATCH] Basic HTML writer --- CHANGELOG.md | 3 +- samples/Sample_01_SimpleText.php | 12 +- samples/Sample_02_TabStops.php | 12 +- samples/Sample_03_Sections.php | 12 +- samples/Sample_04_Textrun.php | 12 +- samples/Sample_05_Multicolumn.php | 12 +- samples/Sample_06_Footnote.php | 12 +- samples/Sample_08_ParagraphPagination.php | 12 +- samples/Sample_09_Tables.php | 12 +- samples/Sample_10_EastAsianFontStyle.php | 12 +- samples/Sample_11_ReadWord2007.php | 13 +- samples/Sample_12_HeaderFooter.php | 13 +- samples/Sample_13_Images.php | 13 +- samples/Sample_14_ListItem.php | 13 +- samples/Sample_15_Link.php | 14 +- samples/Sample_16_Object.php | 14 +- samples/Sample_17_TitleTOC.php | 13 +- samples/Sample_18_Watermark.php | 14 +- samples/Sample_19_TextBreak.php | 14 +- samples/Sample_20_BGColor.php | 12 +- samples/Sample_21_TableRowRules.php | 12 +- samples/Sample_22_CheckBox.php | 12 +- samples/Sample_Footer.php | 23 - samples/Sample_Header.php | 50 ++ samples/index.php | 6 +- src/PhpWord/Element/Title.php | 10 + src/PhpWord/IOFactory.php | 4 +- src/PhpWord/Writer/HTML.php | 589 ++++++++++++++++++++++ tests/PhpWord/Tests/Writer/HTMLTest.php | 105 ++++ 29 files changed, 826 insertions(+), 229 deletions(-) create mode 100644 src/PhpWord/Writer/HTML.php create mode 100644 tests/PhpWord/Tests/Writer/HTMLTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 03400d46..f9bcdd19 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers ## 0.10.0 - Not yet released -This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. +This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. Basic HTML writer is initiated. ### Features @@ -31,6 +31,7 @@ This release marked heavy refactorings on internal code structure with the creat - Endnote: Ability to add endnotes - @ivanlanin - ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198 - ODT Writer: Basic table writing support - @ivanlanin +- HTML Writer: Basic HTML writer initiated - @ivanlanin ### Bugfixes diff --git a/samples/Sample_01_SimpleText.php b/samples/Sample_01_SimpleText.php index 02b78bd7..659686d3 100755 --- a/samples/Sample_01_SimpleText.php +++ b/samples/Sample_01_SimpleText.php @@ -45,13 +45,7 @@ $section->addTextBreak(); $section->addImage('resources/_earth.jpg', array('width'=>18, 'height'=>18)); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_02_TabStops.php b/samples/Sample_02_TabStops.php index dbed59a3..d6e4cdbc 100755 --- a/samples/Sample_02_TabStops.php +++ b/samples/Sample_02_TabStops.php @@ -33,13 +33,7 @@ $section->addText("Left Aligned\tRight Aligned", null, 'rightTab'); $section->addText("\tCenter Aligned", null, 'centerTab'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_03_Sections.php b/samples/Sample_03_Sections.php index 4953b6a6..bfbc84af 100755 --- a/samples/Sample_03_Sections.php +++ b/samples/Sample_03_Sections.php @@ -26,13 +26,7 @@ $section->addHeader()->addText('Header'); $section->addFooter()->addText('Footer'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_04_Textrun.php b/samples/Sample_04_Textrun.php index 354eadfd..f415ca17 100644 --- a/samples/Sample_04_Textrun.php +++ b/samples/Sample_04_Textrun.php @@ -34,13 +34,7 @@ $textrun->addObject('resources/_sheet.xls'); $textrun->addText(' Here is some more text. '); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_05_Multicolumn.php b/samples/Sample_05_Multicolumn.php index 478a8dd0..a3083824 100644 --- a/samples/Sample_05_Multicolumn.php +++ b/samples/Sample_05_Multicolumn.php @@ -36,13 +36,7 @@ $section = $phpWord->addSection(array('breakType' => 'continuous')); $section->addText('Normal paragraph again.'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_06_Footnote.php b/samples/Sample_06_Footnote.php index 75120088..1bec44e4 100755 --- a/samples/Sample_06_Footnote.php +++ b/samples/Sample_06_Footnote.php @@ -38,13 +38,7 @@ $footnote = $section->addFootnote(); $footnote->addText('The reference for this is wrapped in its own line'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_08_ParagraphPagination.php b/samples/Sample_08_ParagraphPagination.php index bf1400a0..57fbab09 100644 --- a/samples/Sample_08_ParagraphPagination.php +++ b/samples/Sample_08_ParagraphPagination.php @@ -46,13 +46,7 @@ $section->addText('Paragraph with pageBreakBefore = true (default: false). ' . null, array('pageBreakBefore' => true)); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_09_Tables.php b/samples/Sample_09_Tables.php index 5af73fb6..fd930b2b 100644 --- a/samples/Sample_09_Tables.php +++ b/samples/Sample_09_Tables.php @@ -85,13 +85,7 @@ $table->addCell(2000, $cellVCentered)->addText('D', null, $cellHCentered); $table->addCell(null, $cellRowContinue); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_10_EastAsianFontStyle.php b/samples/Sample_10_EastAsianFontStyle.php index 39f449c3..44bca8a6 100644 --- a/samples/Sample_10_EastAsianFontStyle.php +++ b/samples/Sample_10_EastAsianFontStyle.php @@ -10,13 +10,7 @@ $header = array('size' => 16, 'bold' => true); $section->addText('中文楷体样式测试',array('name' => '楷体', 'size' => 16, 'color' => '1B2232')); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_11_ReadWord2007.php b/samples/Sample_11_ReadWord2007.php index e5112e2e..09d9cab0 100644 --- a/samples/Sample_11_ReadWord2007.php +++ b/samples/Sample_11_ReadWord2007.php @@ -7,13 +7,8 @@ $source = "resources/{$name}.docx"; echo date('H:i:s'), " Reading contents from `{$source}`", EOL; $phpWord = \PhpOffice\PhpWord\IOFactory::load($source); -// (Re)write contents -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +// Save file +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_12_HeaderFooter.php b/samples/Sample_12_HeaderFooter.php index 15309041..8e053286 100644 --- a/samples/Sample_12_HeaderFooter.php +++ b/samples/Sample_12_HeaderFooter.php @@ -59,15 +59,8 @@ $sec2Header->addText("All pages in Section 2 will Have this!"); $section2->addTextBreak(); $section2->addText('Some text...'); - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_13_Images.php b/samples/Sample_13_Images.php index 4ef325b8..c8199cce 100644 --- a/samples/Sample_13_Images.php +++ b/samples/Sample_13_Images.php @@ -18,16 +18,9 @@ $section->addTextBreak(2); $source = 'http://php.net/images/logos/php-med-trans-light.gif'; $section->addText("Remote image from: {$source}"); $section->addImage($source); -// End code // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_14_ListItem.php b/samples/Sample_14_ListItem.php index 45d9c1a7..cd22df8e 100644 --- a/samples/Sample_14_ListItem.php +++ b/samples/Sample_14_ListItem.php @@ -54,15 +54,8 @@ $section->addListItem('List Item 6', 1, 'myOwnStyle', $predefinedMultilevel, 'P- $section->addListItem('List Item 7', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); $section->addTextBreak(2); - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_15_Link.php b/samples/Sample_15_Link.php index c4435ac0..1bd61e79 100644 --- a/samples/Sample_15_Link.php +++ b/samples/Sample_15_Link.php @@ -16,16 +16,8 @@ $phpWord->addLinkStyle('myOwnLinkStyle', array('bold'=>true, 'color'=>'808000')) $section->addLink('http://www.bing.com', null, 'myOwnLinkStyle'); $section->addLink('http://www.yahoo.com', null, 'myOwnLinkStyle'); -// End code - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_16_Object.php b/samples/Sample_16_Object.php index cb8de6db..af23a00f 100644 --- a/samples/Sample_16_Object.php +++ b/samples/Sample_16_Object.php @@ -11,16 +11,8 @@ $section->addText('You can open this OLE object by double clicking on the icon:' $section->addTextBreak(2); $section->addObject('resources/_sheet.xls'); -// End code - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_17_TitleTOC.php b/samples/Sample_17_TitleTOC.php index 15de531b..b18b1bc9 100644 --- a/samples/Sample_17_TitleTOC.php +++ b/samples/Sample_17_TitleTOC.php @@ -67,16 +67,9 @@ $section->addTitle('Subtitle 3.1.2', 3); $section->addText('Text'); echo date('H:i:s'), " Note: Please refresh TOC manually.", EOL; -// End code // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_18_Watermark.php b/samples/Sample_18_Watermark.php index d0ea786a..313cfbed 100644 --- a/samples/Sample_18_Watermark.php +++ b/samples/Sample_18_Watermark.php @@ -12,16 +12,8 @@ $header = $section->addHeader(); $header->addWatermark('resources/_earth.jpg', array('marginTop' => 200, 'marginLeft' => 55)); $section->addText('The header reference to the current section includes a watermark image.'); -// End code - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_19_TextBreak.php b/samples/Sample_19_TextBreak.php index d7e11ea4..a209ce39 100644 --- a/samples/Sample_19_TextBreak.php +++ b/samples/Sample_19_TextBreak.php @@ -25,16 +25,8 @@ $section->addText('Text break with inline paragraph style:'); $section->addTextBreak(1, null, $paragraphStyle); $section->addText('Done.'); -// End code - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_20_BGColor.php b/samples/Sample_20_BGColor.php index fec40859..892cd8b2 100644 --- a/samples/Sample_20_BGColor.php +++ b/samples/Sample_20_BGColor.php @@ -11,13 +11,7 @@ $section->addText("This one uses bgColor and is using hex value (0xfbbb10)", arr $section->addText("Compatible with font colors", array("color"=>"0000ff", "bgColor" => "fbbb10")); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_21_TableRowRules.php b/samples/Sample_21_TableRowRules.php index 10ad156d..b600ec00 100644 --- a/samples/Sample_21_TableRowRules.php +++ b/samples/Sample_21_TableRowRules.php @@ -28,13 +28,7 @@ $section->addText("In this example, image is 250px height. Rows are calculated i $section->addText("So: $"."table2->addRow(3750, array('exactHeight'=>true));"); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_22_CheckBox.php b/samples/Sample_22_CheckBox.php index 89827388..e7aae5ba 100644 --- a/samples/Sample_22_CheckBox.php +++ b/samples/Sample_22_CheckBox.php @@ -15,13 +15,7 @@ $cell = $table->addCell(); $cell->addCheckBox('chkBox2', 'Checkbox 2'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_Footer.php b/samples/Sample_Footer.php index 4d5777c2..f7e2305f 100644 --- a/samples/Sample_Footer.php +++ b/samples/Sample_Footer.php @@ -2,33 +2,10 @@ /** * Footer file */ -// Do not show execution time for index -if (!IS_INDEX) { - echo date('H:i:s'), " Done writing file(s)", EOL; - echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; -} -// Show message when executed with CLI, show links when using browsers -if (CLI) { - echo 'The results are stored in the "results" subdirectory.', EOL; -} else { - if (!IS_INDEX) { - $types = array('docx', 'odt', 'rtf'); - echo '

 

'; - echo '

Results: '; - foreach ($types as $type) { - $result = 'results/' . SCRIPT_FILENAME . '.' . $type; - if (file_exists($result)) { - echo "{$type} "; - } - } - echo '

'; - } ?> -{$pageHeading}"; + +// Set writers +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf', 'HTML' => 'html'); + // Populate samples $files = ''; if ($handle = opendir('.')) { @@ -32,6 +36,52 @@ if ($handle = opendir('.')) { } closedir($handle); } + +/** + * Get results + * + * @param array $writers + * @param string $filename + * @return string + */ +function write($phpWord, $filename, $writers) +{ + $result = ''; + + // Write + foreach ($writers as $writer => $extension) { + $result .= date('H:i:s') . " Write to {$writer} format" . EOL; + $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); + $xmlWriter->save("{$filename}.{$extension}"); + rename("{$filename}.{$extension}", "results/{$filename}.{$extension}"); + } + + // Do not show execution time for index + if (!IS_INDEX) { + $result .= date('H:i:s') . " Done writing file(s)" . EOL; + $result .= date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" . EOL; + } + + // Return + if (CLI) { + $result .= 'The results are stored in the "results" subdirectory.' . EOL; + } else { + if (!IS_INDEX) { + $types = array_values($writers); + $result .= '

 

'; + $result .= '

Results: '; + foreach ($types as $type) { + $resultFile = 'results/' . SCRIPT_FILENAME . '.' . $type; + if (file_exists($resultFile)) { + $result .= "{$type} "; + } + } + $result .= '

'; + } + } + + return $result; +} ?> <?php echo $pageTitle; ?> diff --git a/samples/index.php b/samples/index.php index 451cf381..8c742729 100644 --- a/samples/index.php +++ b/samples/index.php @@ -24,5 +24,7 @@ foreach ($requirements as $key => $value) { echo "
  • {$value[0]} ... {$status}
  • "; } echo ""; -} // if (!CLI) -include_once 'Sample_Footer.php'; +} +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/src/PhpWord/Element/Title.php b/src/PhpWord/Element/Title.php index 5ed1bfbc..93b48d62 100644 --- a/src/PhpWord/Element/Title.php +++ b/src/PhpWord/Element/Title.php @@ -119,6 +119,16 @@ class Title extends AbstractElement return $this->text; } + /** + * Get depth + * + * @return integer + */ + public function getDepth() + { + return $this->depth; + } + /** * Get Title style * diff --git a/src/PhpWord/IOFactory.php b/src/PhpWord/IOFactory.php index ade4398e..c15ec821 100644 --- a/src/PhpWord/IOFactory.php +++ b/src/PhpWord/IOFactory.php @@ -28,7 +28,7 @@ abstract class IOFactory */ public static function createWriter(PhpWord $phpWord, $name = 'Word2007') { - if ($name !== 'WriterInterface' && $name !== 'ODText' && $name !== 'RTF' && $name !== 'Word2007') { + if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML'))) { throw new Exception("\"{$name}\" is not a valid writer."); } @@ -45,7 +45,7 @@ abstract class IOFactory */ public static function createReader($name = 'Word2007') { - if ($name !== 'ReaderInterface' && $name !== 'Word2007') { + if (!in_array($name, array('ReaderInterface', 'Word2007'))) { throw new Exception("\"{$name}\" is not a valid reader."); } diff --git a/src/PhpWord/Writer/HTML.php b/src/PhpWord/Writer/HTML.php new file mode 100644 index 00000000..797dd9dc --- /dev/null +++ b/src/PhpWord/Writer/HTML.php @@ -0,0 +1,589 @@ +setPhpWord($phpWord); + } + + /** + * Save PhpWord to file + * + * @param string $filename + * @throws Exception + */ + public function save($filename = null) + { + if (!is_null($this->getPhpWord())) { + $hFile = fopen($filename, 'w') or die("can't open file"); + fwrite($hFile, $this->writeDocument()); + fclose($hFile); + } else { + throw new Exception("No PHPWord assigned."); + } + } + + /** + * Get phpWord data + * + * @return string + */ + private function writeDocument() + { + $html = ''; + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= $this->writeHTMLHead(); + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= $this->writeHTMLBody(); + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + + return $html; + } + + /** + * Generate HTML header + * + * @return string + */ + public function writeHTMLHead() + { + $properties = $this->getPhpWord()->getDocumentProperties(); + $propertiesMapping = array( + 'creator' => 'author', + 'title' => '', + 'description' => '', + 'subject' => '', + 'keywords' => '', + 'category' => '', + 'company' => '', + 'manager' => '' + ); + $title = $properties->getTitle(); + $title = ($title != '') ? $title : 'PHPWord'; + + $html = ''; + $html .= '' . PHP_EOL; + $html .= '' . htmlspecialchars($title) . '' . PHP_EOL; + foreach ($propertiesMapping as $key => $value) { + $value = ($value == '') ? $key : $value; + $method = "get" . $key; + if ($properties->$method() != '') { + $html .= '' . PHP_EOL; + } + } + $html .= $this->writeStyles(); + + return $html; + } + + /** + * Get content + * + * @return string + */ + public function writeHTMLBody() + { + $phpWord = $this->getPhpWord(); + $html = ''; + + $sections = $phpWord->getSections(); + $countSections = count($sections); + $pSection = 0; + + if ($countSections > 0) { + foreach ($sections as $section) { + $pSection++; + $cellContents = $section->getElements(); + foreach ($cellContents as $element) { + if ($element instanceof Text) { + $html .= $this->writeText($element); + } elseif ($element instanceof TextRun) { + $html .= $this->writeTextRun($element); + } elseif ($element instanceof Link) { + $html .= $this->writeLink($element); + } elseif ($element instanceof Title) { + $html .= $this->writeTitle($element); + } elseif ($element instanceof PreserveText) { + $html .= $this->writePreserveText($element); + } elseif ($element instanceof TextBreak) { + $html .= $this->writeTextBreak($element); + } elseif ($element instanceof PageBreak) { + $html .= $this->writePageBreak($element); + } elseif ($element instanceof Table) { + $html .= $this->writeTable($element); + } elseif ($element instanceof ListItem) { + $html .= $this->writeListItem($element); + } elseif ($element instanceof Image) { + $html .= $this->writeImage($element); + } elseif ($element instanceof Object) { + $html .= $this->writeObject($element); + } elseif ($element instanceof Footnote) { + $html .= $this->writeFootnote($element, true); + } elseif ($element instanceof Endnote) { + $html .= $this->writeEndnote($element, true); + } + } + } + } + + return $html; + } + + /** + * Get text + * + * @param Text $text + * @param boolean $withoutP + * @return string + */ + private function writeText($text, $withoutP = false) + { + $html = ''; + $paragraphStyle = $text->getParagraphStyle(); + $spIsObject = ($paragraphStyle instanceof Paragraph); + $fontStyle = $text->getFontStyle(); + $sfIsObject = ($fontStyle instanceof Font); + + if ($paragraphStyle && !$withoutP) { + $html .= 'writeParagraphStyle($paragraphStyle) . '"'; + } + $html .= '>'; + } + if ($fontStyle) { + $html .= 'writeFontStyle($fontStyle) . '"'; + } + $html .= '>'; + } + $html .= htmlspecialchars($text->getText()); + if ($fontStyle) { + $html .= ''; + } + if ($paragraphStyle && !$withoutP) { + $html .= '

    ' . PHP_EOL; + } + + return $html; + } + + /** + * Get text run content + * + * @param TextRun $textrun + * @return string + */ + private function writeTextRun($textrun) + { + $html = ''; + $elements = $textrun->getElements(); + if (count($elements) > 0) { + $paragraphStyle = $textrun->getParagraphStyle(); + $spIsObject = ($paragraphStyle instanceof Paragraph); + $html .= 'writeParagraphStyle($paragraphStyle) . '"'; + } + } + $html .= '>'; + foreach ($elements as $element) { + if ($element instanceof Text) { + $html .= $this->writeText($element, true); + } elseif ($element instanceof Link) { + $html .= $this->writeLink($element, true); + } elseif ($element instanceof TextBreak) { + $html .= $this->writeTextBreak($element, true); + } elseif ($element instanceof Image) { + $html .= $this->writeImage($element, true); + } elseif ($element instanceof Footnote) { + $html .= $this->writeFootnote($element, true); + } elseif ($element instanceof Endnote) { + $html .= $this->writeEndnote($element, true); + } + } + $html .= '

    ' . PHP_EOL; + } + + return $html; + } + + /** + * Write link + * + * @param Link $element + * @return string + */ + private function writeLink($element, $withoutP = false) + { + $url = $element->getLinkSrc(); + $text = $element->getLinkName(); + $html = ''; + if (!$withoutP) { + $html .= "

    " . PHP_EOL; + } + $html .= "{$text}" . PHP_EOL; + if (!$withoutP) { + $html .= "

    " . PHP_EOL; + } + + return $html; + } + + /** + * Write heading + * + * @param Title $element + * @return string + */ + private function writeTitle($element) + { + $tag = 'h' . $element->getDepth(); + $text = htmlspecialchars($element->getText()); + $html = "<{$tag}>{$text}" . PHP_EOL; + + return $html; + } + + /** + * Write preserve text + * + * @param PreserveText $element + * @return string + */ + private function writePreserveText($element, $withoutP = false) + { + return $this->writeUnsupportedElement($element, $withoutP); + } + + /** + * Get text break + * + * @param TextBreak $element + * @param boolean $withoutP + * @return string + */ + private function writeTextBreak($element, $withoutP = false) + { + if ($withoutP) { + $html = '
    ' . PHP_EOL; + } else { + $html = '

     

    ' . PHP_EOL; + } + + return $html; + } + + /** + * Write page break + * + * @param PageBreak $element + * @return string + */ + private function writePageBreak($element) + { + return $this->writeUnsupportedElement($element, false); + } + + /** + * Write list item + * + * @param ListItem $element + * @return string + */ + private function writeListItem($element) + { + return $this->writeUnsupportedElement($element, false); + } + + /** + * Write table + * + * @param Title $element + * @return string + */ + private function writeTable($element) + { + $html = ''; + $rows = $element->getRows(); + $cRows = count($rows); + if ($cRows > 0) { + $html .= "" . PHP_EOL; + foreach ($rows as $row) { + $height = $row->getHeight(); + $rowStyle = $row->getStyle(); + $tblHeader = $rowStyle->getTblHeader(); + $html .= "" . PHP_EOL; + foreach ($row->getCells() as $cell) { + $cellTag = $tblHeader ? 'th' : 'td'; + $cellContents = $cell->getElements(); + $html .= "<{$cellTag}>" . PHP_EOL; + if (count($cellContents) > 0) { + foreach ($cellContents as $content) { + if ($content instanceof Text) { + $html .= $this->writeText($content); + } elseif ($content instanceof TextRun) { + $html .= $this->writeTextRun($content); + } elseif ($content instanceof Link) { + $html .= $this->writeLink($content); + } elseif ($content instanceof PreserveText) { + $html .= $this->writePreserveText($content); + } elseif ($content instanceof TextBreak) { + $html .= $this->writeTextBreak($content); + } elseif ($content instanceof ListItem) { + $html .= $this->writeListItem($content); + } elseif ($content instanceof Image) { + $html .= $this->writeImage($content); + } elseif ($content instanceof Object) { + $html .= $this->writeObject($content); + } elseif ($element instanceof Footnote) { + $html .= $this->writeFootnote($element, true); + } elseif ($element instanceof Endnote) { + $html .= $this->writeEndnote($element, true); + } + } + } else { + $this->writeTextBreak($content); + } + $html .= "" . PHP_EOL; + } + $html .= "" . PHP_EOL; + } + $html .= "
    " . PHP_EOL; + } + + return $html; + } + + /** + * Write image + * + * @param Image $element + * @return string + */ + private function writeImage($element, $withoutP = false) + { + return $this->writeUnsupportedElement($element, $withoutP); + } + + /** + * Write object + * + * @param Object $element + * @return string + */ + private function writeObject($element, $withoutP = false) + { + return $this->writeUnsupportedElement($element, $withoutP); + } + + /** + * Write footnote + * + * @param Footnote $element + * @return string + */ + private function writeFootnote($element) + { + return $this->writeUnsupportedElement($element, true); + } + + /** + * Write endnote + * + * @param Endnote $element + * @return string + */ + private function writeEndnote($element) + { + return $this->writeUnsupportedElement($element, true); + } + + /** + * Write unsupported element + * + * @param mixed $element + * @param boolean $withoutP + * @return string + */ + private function writeUnsupportedElement($element, $withoutP = false) + { + $elementClass = get_class($element); + $elementMark = str_replace('PhpOffice\\PhpWord\\Element\\', '', $elementClass); + $elementMark = htmlentities("<{$elementMark}>"); + if ($withoutP) { + $html = "{$elementMark}" . PHP_EOL; + } else { + $html = "

    {$elementMark}

    " . PHP_EOL; + } + + return $html; + } + + /** + * Get styles + * + * @return string + */ + private function writeStyles() + { + $css = '' . PHP_EOL; + + return $css; + } + + /** + * Get font style + * + * @param Font $style + * @param boolean $curlyBracket + * @return string + */ + private function writeFontStyle($style, $curlyBracket = false) + { + $css = array(); + if (PHPWord::DEFAULT_FONT_NAME != $style->getName()) { + $css['font-family'] = "'" . $style->getName() . "'"; + } + if (PHPWord::DEFAULT_FONT_SIZE != $style->getSize()) { + $css['font-size'] = $style->getSize() . 'pt'; + } + if (PHPWord::DEFAULT_FONT_COLOR != $style->getColor()) { + $css['color'] = '#' . $style->getColor(); + } + $css['background'] = $style->getFgColor(); + if ($style->getBold()) { + $css['font-weight'] = 'bold'; + } + if ($style->getItalic()) { + $css['font-style'] = 'italic'; + } + if ($style->getSuperScript()) { + $css['vertical-align'] = 'super'; + } elseif ($style->getSubScript()) { + $css['vertical-align'] = 'sub'; + } + $css['text-decoration'] = ''; + if ($style->getUnderline() != Font::UNDERLINE_NONE) { + $css['text-decoration'] .= 'underline '; + } + if ($style->getStrikethrough()) { + $css['text-decoration'] .= 'line-through '; + } + + return $this->assembleCss($css, $curlyBracket); + } + + /** + * Get paragraph style + * + * @param Paragraph $style + * @param boolean $curlyBracket + * @return string + */ + private function writeParagraphStyle($style, $curlyBracket = false) + { + $css = array(); + if ($style->getAlign()) { + $css['text-align'] = $style->getAlign(); + } + + return $this->assembleCss($css, $curlyBracket); + } + + /** + * Takes array where of CSS properties / values and converts to CSS string + * + * @param array $css + * @param boolean $curlyBracket + * @return string + */ + private function assembleCss($css, $curlyBracket = false) + { + $pairs = array(); + foreach ($css as $key => $value) { + if ($value != '') { + $pairs[] = $key . ': ' . $value; + } + } + $string = implode('; ', $pairs); + if ($curlyBracket) { + $string = '{ ' . $string . ' }'; + } + + return $string; + } +} diff --git a/tests/PhpWord/Tests/Writer/HTMLTest.php b/tests/PhpWord/Tests/Writer/HTMLTest.php new file mode 100644 index 00000000..40ea88b0 --- /dev/null +++ b/tests/PhpWord/Tests/Writer/HTMLTest.php @@ -0,0 +1,105 @@ +assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object->getPhpWord()); + } + + /** + * Construct with null + * + * @expectedException \PhpOffice\PhpWord\Exception\Exception + * @expectedExceptionMessage No PhpWord assigned. + */ + public function testConstructWithNull() + { + $object = new HTML(); + $object->getPhpWord(); + } + + /** + * Save + */ + public function testSave() + { + $imageSrc = __DIR__ . "/../_files/images/PhpWord.png"; + $objectSrc = __DIR__ . "/../_files/documents/sheet.xls"; + $file = __DIR__ . "/../_files/temp.html"; + + $phpWord = new PhpWord(); + + $docProps = $phpWord->getDocumentProperties(); + $docProps->setTitle('HTML Test'); + + $phpWord->addFontStyle('Font', array('name' => 'Verdana', 'size' => 11, 'color' => 'FF0000', 'fgColor' => 'FF0000')); + $phpWord->addParagraphStyle('Paragraph', array('align' => 'center')); + $section = $phpWord->addSection(); + $section->addText('Test 1', 'Font', 'Paragraph'); + $section->addTextBreak(); + $section->addText('Test 2', array('name' => 'Tahoma', 'bold' => true, 'italic' => true)); + $section->addLink('http://test.com'); + $section->addTitle('Test', 1); + $section->addPageBreak(); + $section->addListItem('Test'); + $section->addImage($imageSrc); + $section->addObject($objectSrc); + $section->addFootnote(); + $section->addEndnote(); + + $section = $phpWord->addSection(); + + $textrun = $section->addTextRun(array('align' => 'center')); + $textrun->addText('Test 3'); + $textrun->addTextBreak(); + + $textrun = $section->addTextRun('Paragraph'); + $textrun->addLink('http://test.com'); + $textrun->addImage($imageSrc); + $textrun->addFootnote(); + $textrun->addEndnote(); + + $section = $phpWord->addSection(); + + $table = $section->addTable(); + $cell = $table->addRow()->addCell(); + $cell->addText('Test 1', array('superscript' => true, 'underline' => 'dash', 'strikethrough' => true)); + $cell->addTextRun(); + $cell->addLink('http://test.com'); + $cell->addTextBreak(); + $cell->addListItem('Test'); + $cell->addImage($imageSrc); + $cell->addObject($objectSrc); + $cell->addFootnote(); + $cell->addEndnote(); + + $writer = new HTML($phpWord); + $writer->save($file); + + $this->assertTrue(file_exists($file)); + + unlink($file); + } +}