PHPOffice / PHPWord

A pure PHP library for reading and writing word processing documents
https://phpoffice.github.io/PHPWord/
Other
7.25k stars 2.69k forks source link

absolute image margins ignored #1151

Open omarpiani opened 7 years ago

omarpiani commented 7 years ago

Our source sample are not working

https://github.com/PHPOffice/PHPWord/blob/0beeb275fec44b0db8caaf54e13e1aa612f544e4/samples/Sample_13_Images.php#L52

marginLeft and marginTop are ignored.

Regards

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/50153558-absolute-image-margins-ignored?utm_campaign=plugin&utm_content=tracker%2F323108&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F323108&utm_medium=issues&utm_source=github).
FBnil commented 7 years ago

I use (PHP 7.0, LibreOffice 5.4.1.2). Which version of MSOffice are you using? Can you attach a document, or put the document.xml (inside the docx) on pastebin, for me to compare it?

Did you isolate the command? (for example, in Laravel):

Route::get('/test9', function () {
    $phpWord = new \PhpOffice\PhpWord\PhpWord();
    $section = $phpWord->addSection();

//Absolute positioning
$section->addTextBreak(3);
$section->addText('Absolute positioning: see top right corner of page');
$section->addImage(
    storage_path('_mars.jpg'), # sets the path to ./storage/
    array(
        'width'            => round(\PhpOffice\PhpWord\Shared\Converter::cmToPixel(3)),
        'height'           => round(\PhpOffice\PhpWord\Shared\Converter::cmToPixel(3)),
        'positioning'      => \PhpOffice\PhpWord\Style\Image::POSITION_ABSOLUTE,
        'posHorizontal'    => \PhpOffice\PhpWord\Style\Image::POSITION_HORIZONTAL_RIGHT,
        'posVertical'    => \PhpOffice\PhpWord\Style\Image::POSITION_VERTICAL_TOP,
        'posHorizontalRel' => \PhpOffice\PhpWord\Style\Image::POSITION_RELATIVE_TO_PAGE,
        'posVerticalRel'   => \PhpOffice\PhpWord\Style\Image::POSITION_RELATIVE_TO_PAGE,
        'marginLeft'       => round(\PhpOffice\PhpWord\Shared\Converter::cmToPixel(15.5)),
        'marginTop'        => round(\PhpOffice\PhpWord\Shared\Converter::cmToPixel(1.55)),
    )
);

        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $save_file_name =storage_path("/app/public/xyz.docx") ;
        $objWriter->save($save_file_name);
        return response()->download($save_file_name)->deleteFileAfterSend(true);
});

You are right though, I can not get the margins to work, even if I round() them

https://msdn.microsoft.com/en-us/library/ee908652(v=office.12).aspx

Exported data is in a v:shape

<w:pict>
  <v:shape type="#_x0000_t75" style="width:113px; height:113px; margin-left:113px; margin-top:113px; position:absolute; mso-position-horizontal:right; mso-position-vertical:top; mso-position-horizontal-relative:page; mso-position-vertical-relative:page;">
<w10:wrap type="inline" anchory="page" anchorx="page"/>
<v:imagedata o:title="" r:id="rId7"/>
</v:shape>

after editing with LibreOffice, it is a v:rect:

<w:pict>
<v:rect id="shape_0" stroked="f" style="position:absolute;margin-left:2.9pt;margin-top:2.9pt;width:45.55pt;height:45.55pt;
mso-position-horizontal-relative:page;mso-position-vertical-relative:page">
  <v:imagedata r:id="rId2" o:detectmouseclick="t"/>
  <w10:wrap type="none"/>
  <v:stroke color="#3465a4" joinstyle="round" endcap="flat"/>
</v:rect>
</w:pict>

LibreOffice shows that mso-position-vertical:top gives a top, and not a from-top in the GUI, and thus, the selector is grayed out.

omarpiani commented 7 years ago

I have MS Word 2017 and I use PHP 7.1, included in composer with "phpoffice/phpword": "dev-develop"


<?php
include_once './vendor/autoload.php';
use PhpOffice\PhpWord\PhpWord;
$word = new PhpWord();
$section = $word->addSection();
$section->addImage(
   'test.png',
    array(
        'width'            => round(\PhpOffice\PhpWord\Shared\Converter::cmToPixel(3)),
        'height'           => round(\PhpOffice\PhpWord\Shared\Converter::cmToPixel(3)),
        'positioning'      => \PhpOffice\PhpWord\Style\Image::POSITION_ABSOLUTE,
        'posHorizontal'    => \PhpOffice\PhpWord\Style\Image::POSITION_HORIZONTAL_RIGHT,
        'posVertical'    => \PhpOffice\PhpWord\Style\Image::POSITION_VERTICAL_TOP,
        'posHorizontalRel' => \PhpOffice\PhpWord\Style\Image::POSITION_RELATIVE_TO_PAGE,
        'posVerticalRel'   => \PhpOffice\PhpWord\Style\Image::POSITION_RELATIVE_TO_PAGE,
        'marginLeft'       => round(\PhpOffice\PhpWord\Shared\Converter::cmToPixel(15.5)),
        'marginTop'        => round(\PhpOffice\PhpWord\Shared\Converter::cmToPixel(1.55)),
    )
);

if (ob_get_level() > 0) {
    ob_end_clean();
}

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=test.docx");
header("Content-Transfer-Encoding: Binary");

$temp_dir = sys_get_temp_dir();
$temp_file = $temp_dir . '/TestPHPWord' . rand(0, getrandmax()) . rand(0, getrandmax()) . ".tmp";
$word->save($temp_file);
readfile($temp_file);
unlink($temp_file);

Here my generated file: test.docx

The comment "Absolute positioning: see top right corner of page" give me the sensation that margin ignoration is a known behaviour.

Tnx!

AntonMerenkov commented 6 years ago

Please try add this options to $section->addImage(..):

'posHorizontal' => 'absolute',
'posVertical' => 'absolute',

In default, 'posHorizontal' is set to 'left', and 'posVertical' is set to 'top', but this options don't works properly.