本文概述
许多PHP应用程序需要以Microsoft Word格式导出文档, 使用PHPWord可以轻松实现此任务。 PHPWord是一个用纯PHP编写的库, 它提供了一组用于读写不同文档文件格式的类。当前版本的PHPWord支持Microsoft Office Open XML(OOXML或OpenXML), 用于Office应用程序的OASIS开放文档格式(OpenDocument或ODF), 富文本格式(RTF), HTML和PDF。 PHPWord是根据LGPL版本3的条款许可的开源项目。PHPWord旨在通过结合持续的集成和单元测试, 成为一种高质量的软件产品。你可以通过阅读开发人员文档和API文档来了解有关PHPWord的更多信息。
使用PHPWord, 你可以从头开始创建漂亮的Word和PDF文档。创建模板并仅编辑一些变量即可简化Word文档的创建。在本文中, 你将学习如何在Symfony 3项目中实现PHPWord。
要求
如前所述, 为了使用PHP创建Word文件, 我们将依赖于PHPWord库。要将此库作为依赖项安装在你的Symfony项目中, 请在终端中执行以下命令:
composer install phpoffice/phpword
或修改项目的composer.json文件并手动添加该库, 然后执行composer install:
{
"require": {
"phpoffice/phpword": "v0.13.*"
}
}
下载后, 你的项目应具有可用的PhpWord。如果你想要有关此库的更多信息, 请访问官方的Github存储库。
例子
在本文中, 我们将介绍开发人员在使用PHPWord时最常用的4种功能。如果你需要更多示例, 我们建议你在此处检查所有PHPWord示例(尽管它们不是基于Symfony的, 但我相信你会了解如何使用它们)。
注意
在示例中, 我们使用Word2007 writter(OOXML文件)来提高文档的兼容性。此外, 作为Symfony的一种良好做法, 你可能希望使控制器尽可能的薄, 因此我们建议你创建服务
1.流化生成的文件
可惜的是, Phpword writter没有提供任何流式传输文档的方法, 此外, 如果文档存在, 它在我们与Symfony合作时也不会有用。要返回生成的文件作为响应, 你需要先创建该文件, 然后使用BinaryFileResponse类将其发送, 但是, 我们不会在服务器中某个位置创建文件然后删除它的问题。为了简单起见, 你可以使用tempnam(sys_get_temp_dir(), ” filename.extension”)在系统中创建一个临时文件。
以下控制器创建一个word文件, 并立即将其作为附件返回:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
// Include the BinaryFileResponse and the ResponseHeaderBag
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
// Include the requires classes of Phpword
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\IOFactory;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
// Create a new Word document
$phpWord = new PhpWord();
/* Note: any element you append to a document must reside inside of a Section. */
// Adding an empty Section to the document...
$section = $phpWord->addSection();
// Adding Text element to the Section having font styled by default...
$section->addText(
'"Learn from yesterday, live for today, hope for tomorrow. '
. 'The important thing is not to stop questioning." '
. '(Albert Einstein)'
);
// Saving the document as OOXML file...
$objWriter = IOFactory::createWriter($phpWord, 'Word2007');
// Create a temporal file in the system
$fileName = 'hello_world_download_file.docx';
$temp_file = tempnam(sys_get_temp_dir(), $fileName);
// Write in the temporal filepath
$objWriter->save($temp_file);
// Send the temporal file as response (as an attachment)
$response = new BinaryFileResponse($temp_file);
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT, $fileName
);
return $response;
}
}
2.将文件保存在服务器中
默认情况下, 你可以使用writer的save方法在本地路径中写入生成的word文件, 并为目标路径提供filename作为第一个参数:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
// The response object
use Symfony\Component\HttpFoundation\Response;
// Include the requires classes of Phpword
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\IOFactory;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
// Create a new Word document
$phpWord = new PhpWord();
/* Note: any element you append to a document must reside inside of a Section. */
// Adding an empty Section to the document...
$section = $phpWord->addSection();
// Adding Text element to the Section having font styled by default...
$section->addText(
'"Learn from yesterday, live for today, hope for tomorrow. '
. 'The important thing is not to stop questioning." '
. '(Albert Einstein)'
);
// Saving the document as OOXML file...
$objWriter = IOFactory::createWriter($phpWord, 'Word2007');
$filePath = 'hello_world_serverfile.docx';
// Write file into path
$objWriter->save($filePath);
return new Response("File succesfully written at $filePath");
}
}
3.在Word文档中插入图像
要添加图像, 可以使用PhpWord类中可用的addImage方法:
注意
在示例中, 我们使用官方存储库中提供的以下演示图像(earth.jpg)进行测试。
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
// Return a text response
use Symfony\Component\HttpFoundation\Response;
// Include the requires classes of Phpword
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\Style\Image;
use PhpOffice\PhpWord\Shared\Converter;
use PhpOffice\PhpWord\SimpleType\Jc;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
$phpWord = new PhpWord();
// Get the path the the images folder in Symfony
$imagesFolder = $this->get('kernel')->getRootDir() . '/../web/images/';
$_local_image_path = $imagesFolder.'earth.jpg';
// Begin code
$section = $phpWord->addSection();
$section->addText('Local image without any styles:');
$section->addImage($_local_image_path);
$section->addTextBreak(2);
$section->addText('Local image with styles:');
$section->addImage($_local_image_path, array('width' => 210, 'height' => 210, 'alignment' => Jc::CENTER));
$section->addTextBreak(2);
// 1) Add a remote image
$source = 'http://php.net/images/logos/php-med-trans-light.gif';
$section->addText("Remote image from: {$source}");
$section->addImage($source);
// Wrapping style
$text = str_repeat('Hello World! ', 15);
$wrappingStyles = array('inline', 'behind', 'infront', 'square', 'tight');
foreach ($wrappingStyles as $wrappingStyle) {
$section->addTextBreak(5);
$section->addText("Wrapping style {$wrappingStyle}");
$section->addImage(
$_local_image_path, array(
'positioning' => 'relative', 'marginTop' => -1, 'marginLeft' => 1, 'width' => 80, 'height' => 80, 'wrappingStyle' => $wrappingStyle, )
);
$section->addText($text);
}
//Absolute positioning
$section->addTextBreak(3);
$section->addText('Absolute positioning: see top right corner of page');
$section->addImage(
$_local_image_path, array(
'width' => Converter::cmToPixel(3), 'height' => Converter::cmToPixel(3), 'positioning' => Image::POSITION_ABSOLUTE, 'posHorizontal' => Image::POSITION_HORIZONTAL_RIGHT, 'posHorizontalRel' => Image::POSITION_RELATIVE_TO_PAGE, 'posVerticalRel' => Image::POSITION_RELATIVE_TO_PAGE, 'marginLeft' => Converter::cmToPixel(15.5), 'marginTop' => Converter::cmToPixel(1.55), )
);
//Relative positioning
$section->addTextBreak(3);
$section->addText('Relative positioning: Horizontal position center relative to column, ');
$section->addText('Vertical position top relative to line');
$section->addImage(
$_local_image_path, array(
'width' => Converter::cmToPixel(3), 'height' => Converter::cmToPixel(3), 'positioning' => Image::POSITION_RELATIVE, 'posHorizontal' => Image::POSITION_HORIZONTAL_CENTER, 'posHorizontalRel' => Image::POSITION_RELATIVE_TO_COLUMN, 'posVertical' => Image::POSITION_VERTICAL_TOP, 'posVerticalRel' => Image::POSITION_RELATIVE_TO_LINE, )
);
// Saving the document as OOXML file...
$objWriter = IOFactory::createWriter($phpWord, 'Word2007');
$filePath = 'hello_world_images.docx';
// Write file into path
$objWriter->save($filePath);
return new Response("File succesfully written at $filePath");
}
}
4.在图表文件中插入图表
在Word中, 图表非常适合以图形方式显示信息, 并且也很容易用PHPWord添加它们(EMU用于基于矢量的图形和嵌入式图片中的坐标):
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
// Return a text response
use Symfony\Component\HttpFoundation\Response;
// Include the requires classes of Phpword
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\Shared\Converter;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
$phpWord = new PhpWord();
// Define styles
$phpWord->addTitleStyle(1, array('size' => 14, 'bold' => true), array('keepNext' => true, 'spaceBefore' => 240));
$phpWord->addTitleStyle(2, array('size' => 14, 'bold' => true), array('keepNext' => true, 'spaceBefore' => 240));
// 2D charts
$section = $phpWord->addSection();
$section->addTitle('2D charts', 1);
$section = $phpWord->addSection(array('colsNum' => 2, 'breakType' => 'continuous'));
$chartTypes = array('pie', 'doughnut', 'bar', 'column', 'line', 'area', 'scatter', 'radar');
$twoSeries = array('bar', 'column', 'line', 'area', 'scatter', 'radar');
$threeSeries = array('bar', 'line');
$categories = array('A', 'B', 'C', 'D', 'E');
$series1 = array(1, 3, 2, 5, 4);
$series2 = array(3, 1, 7, 2, 6);
$series3 = array(8, 3, 2, 5, 4);
foreach ($chartTypes as $chartType) {
$section->addTitle(ucfirst($chartType), 2);
$chart = $section->addChart($chartType, $categories, $series1);
$chart->getStyle()->setWidth(Converter::inchToEmu(2.5))->setHeight(Converter::inchToEmu(2));
if (in_array($chartType, $twoSeries)) {
$chart->addSeries($categories, $series2);
}
if (in_array($chartType, $threeSeries)) {
$chart->addSeries($categories, $series3);
}
$section->addTextBreak();
}
// 3D charts
$section = $phpWord->addSection(array('breakType' => 'continuous'));
$section->addTitle('3D charts', 1);
$section = $phpWord->addSection(array('colsNum' => 2, 'breakType' => 'continuous'));
$chartTypes = array('pie', 'bar', 'column', 'line', 'area');
$multiSeries = array('bar', 'column', 'line', 'area');
$style = array('width' => Converter::cmToEmu(5), 'height' => Converter::cmToEmu(4), '3d' => true);
foreach ($chartTypes as $chartType) {
$section->addTitle(ucfirst($chartType), 2);
$chart = $section->addChart($chartType, $categories, $series1, $style);
if (in_array($chartType, $multiSeries)) {
$chart->addSeries($categories, $series2);
$chart->addSeries($categories, $series3);
}
$section->addTextBreak();
}
// Saving the document as OOXML file...
$objWriter = IOFactory::createWriter($phpWord, 'Word2007');
$filePath = 'hello_world_charts.docx';
// Write file into path
$objWriter->save($filePath);
return new Response("File succesfully written at $filePath");
}
}
我们建议你阅读文档, 以了解使用PHPWord可以做的所有令人敬畏的事情。
编码愉快!
评论前必须登录!
注册