Word2007.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. /**
  3. * PHPWord
  4. *
  5. * Copyright (c) 2011 PHPWord
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * @category PHPWord
  22. * @package PHPWord
  23. * @copyright Copyright (c) 010 PHPWord
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version Beta 0.6.3, 08.07.2011
  26. */
  27. class PHPWord_Writer_Word2007 implements PHPWord_Writer_IWriter {
  28. private $_document;
  29. private $_writerParts;
  30. private $_diskCachingDirectory;
  31. private $_useDiskCaching = false;
  32. private $_imageTypes = array();
  33. private $_objectTypes = array();
  34. public function __construct(PHPWord $PHPWord = null) {
  35. $this->_document = $PHPWord;
  36. $this->_diskCachingDirectory = './';
  37. $this->_writerParts['contenttypes'] = new PHPWord_Writer_Word2007_ContentTypes();
  38. $this->_writerParts['rels'] = new PHPWord_Writer_Word2007_Rels();
  39. $this->_writerParts['docprops'] = new PHPWord_Writer_Word2007_DocProps();
  40. $this->_writerParts['documentrels'] = new PHPWord_Writer_Word2007_DocumentRels();
  41. $this->_writerParts['document'] = new PHPWord_Writer_Word2007_Document();
  42. $this->_writerParts['styles'] = new PHPWord_Writer_Word2007_Styles();
  43. $this->_writerParts['header'] = new PHPWord_Writer_Word2007_Header();
  44. $this->_writerParts['footer'] = new PHPWord_Writer_Word2007_Footer();
  45. foreach($this->_writerParts as $writer) {
  46. $writer->setParentWriter($this);
  47. }
  48. }
  49. public function save($pFilename = null) {
  50. if(!is_null($this->_document)) {
  51. // If $pFilename is php://output or php://stdout, make it a temporary file...
  52. $originalFilename = $pFilename;
  53. if(strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
  54. $pFilename = @tempnam('./', 'phppttmp');
  55. if($pFilename == '') {
  56. $pFilename = $originalFilename;
  57. }
  58. }
  59. // Create new ZIP file and open it for writing
  60. $objZip = new ZipArchive();
  61. // Try opening the ZIP file
  62. if($objZip->open($pFilename, ZIPARCHIVE::OVERWRITE) !== true) {
  63. if($objZip->open($pFilename, ZIPARCHIVE::CREATE) !== true) {
  64. throw new Exception("Could not open " . $pFilename . " for writing.");
  65. }
  66. }
  67. $sectionElements = array();
  68. $_secElements = PHPWord_Media::getSectionMediaElements();
  69. foreach($_secElements as $element) { // loop through section media elements
  70. if($element['type'] != 'hyperlink') {
  71. $this->_addFileToPackage($objZip, $element);
  72. }
  73. $sectionElements[] = $element;
  74. }
  75. $_hdrElements = PHPWord_Media::getHeaderMediaElements();
  76. foreach($_hdrElements as $_headerFile => $_hdrMedia) { // loop through headers
  77. if(count($_hdrMedia) > 0) {
  78. $objZip->addFromString('word/_rels/'.$_headerFile.'.xml.rels', $this->getWriterPart('documentrels')->writeHeaderFooterRels($_hdrMedia));
  79. foreach($_hdrMedia as $element) { // loop through header media elements
  80. $this->_addFileToPackage($objZip, $element);
  81. }
  82. }
  83. }
  84. $_ftrElements = PHPWord_Media::getFooterMediaElements();
  85. foreach($_ftrElements as $_footerFile => $_ftrMedia) { // loop through footers
  86. if(count($_ftrMedia) > 0) {
  87. $objZip->addFromString('word/_rels/'.$_footerFile.'.xml.rels', $this->getWriterPart('documentrels')->writeHeaderFooterRels($_ftrMedia));
  88. foreach($_ftrMedia as $element) { // loop through footers media elements
  89. $this->_addFileToPackage($objZip, $element);
  90. }
  91. }
  92. }
  93. $_cHdrs = 0;
  94. $_cFtrs = 0;
  95. $rID = PHPWord_Media::countSectionMediaElements() + 6;
  96. $_sections = $this->_document->getSections();
  97. foreach($_sections as $section) {
  98. $_header = $section->getHeader();
  99. if(!is_null($_header)) {
  100. $_cHdrs++;
  101. $_header->setRelationId(++$rID);
  102. $_headerCount = $_header->getHeaderCount();
  103. $_headerFile = 'header'.$_headerCount.'.xml';
  104. $sectionElements[] = array('target'=>$_headerFile, 'type'=>'header', 'rID'=>$rID);
  105. $objZip->addFromString('word/'.$_headerFile, $this->getWriterPart('header')->writeHeader($_header));
  106. }
  107. $_footer = $section->getFooter();
  108. if(!is_null($_footer)) {
  109. $_cFtrs++;
  110. $_footer->setRelationId(++$rID);
  111. $_footerCount = $_footer->getFooterCount();
  112. $_footerFile = 'footer'.$_footerCount.'.xml';
  113. $sectionElements[] = array('target'=>$_footerFile, 'type'=>'footer', 'rID'=>$rID);
  114. $objZip->addFromString('word/'.$_footerFile, $this->getWriterPart('footer')->writeFooter($_footer));
  115. }
  116. }
  117. // build docx file
  118. // Write dynamic files
  119. $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('contenttypes')->writeContentTypes($this->_imageTypes, $this->_objectTypes, $_cHdrs, $_cFtrs));
  120. $objZip->addFromString('_rels/.rels', $this->getWriterPart('rels')->writeRelationships($this->_document));
  121. $objZip->addFromString('docProps/app.xml', $this->getWriterPart('docprops')->writeDocPropsApp($this->_document));
  122. $objZip->addFromString('docProps/core.xml', $this->getWriterPart('docprops')->writeDocPropsCore($this->_document));
  123. $objZip->addFromString('word/document.xml', $this->getWriterPart('document')->writeDocument($this->_document));
  124. $objZip->addFromString('word/_rels/document.xml.rels', $this->getWriterPart('documentrels')->writeDocumentRels($sectionElements));
  125. $objZip->addFromString('word/styles.xml', $this->getWriterPart('styles')->writeStyles($this->_document));
  126. // Write static files
  127. $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/numbering.xml', 'word/numbering.xml');
  128. $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/settings.xml', 'word/settings.xml');
  129. $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/theme1.xml', 'word/theme/theme1.xml');
  130. $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/webSettings.xml', 'word/webSettings.xml');
  131. $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/fontTable.xml', 'word/fontTable.xml');
  132. // Close file
  133. if($objZip->close() === false) {
  134. throw new Exception("Could not close zip file $pFilename.");
  135. }
  136. // If a temporary file was used, copy it to the correct file stream
  137. if($originalFilename != $pFilename) {
  138. if (copy($pFilename, $originalFilename) === false) {
  139. throw new Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
  140. }
  141. @unlink($pFilename);
  142. }
  143. } else {
  144. throw new Exception("PHPWord object unassigned.");
  145. }
  146. }
  147. private function _chkContentTypes($src) {
  148. $srcInfo = pathinfo($src);
  149. $extension = strtolower($srcInfo['extension']);
  150. if(substr($extension, 0, 3) == 'php') {
  151. $extension = 'php';
  152. }
  153. $_supportedImageTypes = array('jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff', 'php');
  154. if(in_array($extension, $_supportedImageTypes)) {
  155. $imagedata = getimagesize($src);
  156. $imagetype = image_type_to_mime_type($imagedata[2]);
  157. $imageext = image_type_to_extension($imagedata[2]);
  158. $imageext = str_replace('.', '', $imageext);
  159. if($imageext == 'jpeg') $imageext = 'jpg';
  160. if(!in_array($imagetype, $this->_imageTypes)) {
  161. $this->_imageTypes[$imageext] = $imagetype;
  162. }
  163. } else {
  164. if(!in_array($extension, $this->_objectTypes)) {
  165. $this->_objectTypes[] = $extension;
  166. }
  167. }
  168. }
  169. public function getWriterPart($pPartName = '') {
  170. if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) {
  171. return $this->_writerParts[strtolower($pPartName)];
  172. } else {
  173. return null;
  174. }
  175. }
  176. public function getUseDiskCaching() {
  177. return $this->_useDiskCaching;
  178. }
  179. public function setUseDiskCaching($pValue = false, $pDirectory = null) {
  180. $this->_useDiskCaching = $pValue;
  181. if (!is_null($pDirectory)) {
  182. if (is_dir($pDirectory)) {
  183. $this->_diskCachingDirectory = $pDirectory;
  184. } else {
  185. throw new Exception("Directory does not exist: $pDirectory");
  186. }
  187. }
  188. return $this;
  189. }
  190. private function _addFileToPackage($objZip, $element) {
  191. if(isset($element['isMemImage']) && $element['isMemImage']) {
  192. $image = call_user_func($element['createfunction'], $element['source']);
  193. ob_start();
  194. call_user_func($element['imagefunction'], $image);
  195. $imageContents = ob_get_contents();
  196. ob_end_clean();
  197. $objZip->addFromString('word/'.$element['target'], $imageContents);
  198. imagedestroy($image);
  199. $this->_chkContentTypes($element['source']);
  200. } else {
  201. $objZip->addFile($element['source'], 'word/'.$element['target']);
  202. $this->_chkContentTypes($element['source']);
  203. }
  204. }
  205. }
  206. ?>