PHPOffice\PHPPresentation 使用Placeholder添加sldNum页码设置字体和页码位置BUG修复以及无法显示页码问题
- by chenxue4076
- 7 years ago
被PHPPresentation的页码设置折腾了好几天,一直以为是自己的代码写的有问题,先说说目前我遇到的BUG
1.在Master或Slide中设置的Placeholder页码位置和大小无效,生成的PPT Placeholder始终在左上角0,0的位置。
2.为Placeholder设置的字体属性不生效,比如大小,居中等。
3.设置垂直居中需要不可以使用fontAlgn,不生效。
以下是解决方法:
修改文件 PHPOffice/PHPPresentation/src/PhpPresentation/Writer/PowerPoint2007/AbstractSlide.php
找到方法名
protected function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeId)
1.注释代码
1)找到代码
if (!$shape->isPlaceholder()) {
// p:sp\p:spPr\a:xfrm
将if一行注释 这里是设置RichText的相关位置的,注释掉就可以将位置信息应用给Placeholder,否则位置在0,0
//if (!$shape->isPlaceholder()) {
// p:sp\p:spPr\a:xfrm
...
//}
2)找到代码
if (!$shape->isPlaceholder()) {
$verticalAlign = $shape->getActiveParagraph()->getAlignment()->getVertical();
将if一行注释 这里设置的垂直居中,如果不注释掉垂直方向无法设置位置,文字只在顶部
//if (!$shape->isPlaceholder()) {
$verticalAlign = $shape->getActiveParagraph()->getAlignment()->getVertical();
...
//}
2.添加代码
1)找到代码
if ($shape->isPlaceholder() &&
($shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_SLIDENUM ||
$shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_DATETIME)
) {
$objWriter->startElement('a:p');
在其后添加下面代码,主要是水平居中,margin值得设置等等
//TODO 此处为chenxue4076@163.com手动添加,为了是页码也能够使用到样式
//TODO 1添加排版信息
$paragraph =$shape->getActiveParagraph()->getAlignment();
//a:pPr
$objWriter->startElement('a:pPr');
$objWriter->writeAttribute('algn', $paragraph->getHorizontal());
$objWriter->writeAttribute('fontAlgn', $paragraph->getVertical());
$objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getMarginLeft()));
$objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu($paragraph->getMarginRight()));
$objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getIndent()));
$objWriter->writeAttribute('lvl', $paragraph->getLevel());
$objWriter->startElement('a:lnSpc');
$objWriter->startElement('a:spcPct');
$objWriter->writeAttribute('val', $shape->getActiveParagraph()->getLineSpacing() . "%");
$objWriter->endElement();
$objWriter->endElement();
$objWriter->endElement();
//TODO 1 END 添加排版信息
//TODO END 此处为chenxue4076@163.com手动添加,为了是页码也能够使用到样式
2)继续往下查找到代码
$objWriter->startElement('a:fld');
$objWriter->writeAttribute('id', $this->getGUID());
$objWriter->writeAttribute('type', (
$shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_SLIDENUM ? 'slidenum' : 'datetime'));
在其后添加下面代码,主要是字体信息,比如加粗,字体类型,大小等信息
//TODO 此处为chenxue4076@163.com手动添加,为了是页码也能够使用到样式
//TODO 2 添加字体信息
$font = $shape->getActiveParagraph()->getFont();
// a:rPr
$objWriter->startElement('a:rPr');
$objWriter->writeAttributeIf($font->isBold(), 'b', '1');
$objWriter->writeAttributeIf($font->isItalic(), 'i', '1');
$objWriter->writeAttributeIf($font->isStrikethrough(), 'strike', 'sngStrike');
// Size
$objWriter->writeAttribute('sz', ($font->getSize() * 100));
// Character spacing
$objWriter->writeAttribute('spc', $font->getCharacterSpacing());
// Underline
$objWriter->writeAttribute('u', $font->getUnderline());
// Color - a:solidFill
$objWriter->startElement('a:solidFill');
$this->writeColor($objWriter, $font->getColor());
$objWriter->endElement();
// Font - a:latin
$objWriter->startElement('a:latin');
$objWriter->writeAttribute('typeface', $font->getName());
$objWriter->endElement();
// a:rPr
$objWriter->endElement();
//TODO 2 添加字体信息
//TODO END 此处为chenxue4076@163.com手动添加,为了是页码也能够使用到样式
经过以上几步设置,现在使用Placehoder 的 sldNum 已经能正常设置文字属性和位置了
下面是生成页码的函数方法,仅供参考
/**
* @param PhpOffice\PhpPresentation\Slide $oSlide
* @param string|array $text
* @param float $width
* @param float $height
* @param float $offsetX
* @param float $offsetY
* @param int $lineSpacing
* @param boolean|array $font
* @param boolean|array $shadow
* @return PhpOffice\PhpPresentation\Slide $oSlide
* @throws Exception
*/
protected function shapeSlideNum($oSlide, $text, $width, $height, $offsetX, $offsetY, $lineSpacing = 100, $font = array(), $shadow = array())
{
$oShape = $oSlide->createRichTextShape();
$oShape->setOffsetX(Drawing::centimetersToPixels($offsetX))
->setOffsetY(Drawing::centimetersToPixels($offsetY))
->setWidth(Drawing::centimetersToPixels($width))
->setHeight(Drawing::centimetersToPixels($height));
$oShape->getActiveParagraph()->setLineSpacing($lineSpacing);
$oFont = new Font();
$oFont->setSize(empty($font['size']) ? 10 : $font['size'])
->setBold( empty($font['bold']) ? false : true)
->setItalic( empty($font['italic']) ? false : true)
->setName(isset($font['family']) ? $font['family'] : '华文细黑')
->setColor(new Color(empty($font['color']) ? 'ff4d4d4d' : $font['color']));
if( ! empty($font['h_align'])) {
$oShape->getActiveParagraph()->getAlignment()->setHorizontal($font['h_align']);
}
if( ! empty($font['v_align'])) {
$oShape->getActiveParagraph()->getAlignment()->setVertical($font['v_align']);
}
$oShape->getActiveParagraph()->setFont($oFont);
if( ! empty($shadow)) {
$oShape->getShadow()->setVisible(true)->setAlpha(isset($shadow['alpha']) ? $shadow['alpha'] : 100)->setDistance(isset($shadow['distance']) ? $shadow['distance'] : 2)->setDirection(isset($shadow['direction']) ? $shadow['direction'] : 45)->setBlurRadius(isset($shadow['blur_radius']) ? $shadow['blur_radius'] : 0)->setColor(new Color(isset($shadow['color']) ? $shadow['color'] : 'ff808080'));
}
//$oShape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_SLIDENUM))->getPlaceholder()->setIdx($oShape->getPlaceholder()->getIdx());
$oShape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_SLIDENUM));
return $oSlide;
}
经过以上设置,我们的代码添加页码就和添加其他元素一样简单了。
附件已经打包,可直接将此文件覆盖到原文件,但是不建议这样做,可能因为版本升级代码变化等原因影响到就不好了,附件地址 AbstractSlide.php.zip
如果是行间距显示有问题,可以将
$objWriter->writeAttribute(‘val’, $shape->getActiveParagraph()->getLineSpacing() . “%”);
修改为
$objWriter->writeAttribute(‘val’, $shape->getActiveParagraph()->getLineSpacing() * 1000);
具体原因请查看
PHPOffice\PHPPresentation文本段落兼容WPS
(208)