Вопрос по php – FPDI / FPDF: водяной знак и печать нескольких страниц

4

Я изменил этот вопрос стека:Применение водяных знаков к файлам PDF, когда пользователи пытаются загрузить файлы но я столкнулся с ошибкой, хотя был комментарий, в котором говорилось о том, как ее исправить, он был недостаточно подробным.

Вот код:

require_once('fpdf/fpdf.php');
require_once('fpdi/fpdi.php');

class WaterMark

{
    public $pdf, $file, $newFile,
        $wmText = "STACKOVERFLOW";

/** $file and $newFile have to include the full path. */
public function __construct($file, $newFile)
{
    $this->pdf = new FPDI();
    $this->file = $file;
    $this->newFile = $newFile;
}

/** $file and $newFile have to include the full path. */
public static function applyAndSpit($file, $newFile)
{
    $wm = new WaterMark($file, $newFile);

    if($wm->isWaterMarked())
        return $wm->spitWaterMarked();
    else{
        $wm->doWaterMark();
        return $wm->spitWaterMarked();
    }
}

/** @todo Make the text nicer and add to all pages */
public function doWaterMark()
{
    $currentFile = $this->file;
    $newFile = $this->newFile;

    $this->pdf->addPage();
    $pagecount = $this->pdf->setSourceFile($currentFile);

    for($i = 1; $i <= $pagecount; $i++){
        $tplidx = $this->pdf->importPage($i);
        $this->pdf->useTemplate($tplidx, 10, 10, 100);
        // now write some text above the imported page
        $this->pdf->SetFont('Arial', 'I', 40);
        $this->pdf->SetTextColor(255,0,0);
        $this->pdf->SetXY(25, 135);
        $this->_rotate(55);
        $this->pdf->Write(0, $this->wmText);
    }

    $this->pdf->Output($newFile, 'F');
}

public function isWaterMarked()
{
    return (file_exists($this->newFile));
}

public function spitWaterMarked()
{
    return readfile($this->newFile);
}

protected function _rotate($angle,$x=-1,$y=-1) {

    if($x==-1)
        $x=$this->pdf->x;
    if($y==-1)
        $y=$this->pdf->y;
    if($this->pdf->angle!=0)
        $this->pdf->_out('Q');
    $this->pdf->angle=$angle;

    if($angle!=0){
        $angle*=M_PI/180;
        $c=cos($angle);
        $s=sin($angle);
        $cx=$x*$this->pdf->k;
        $cy=($this->pdf->h-$y)*$this->pdf->k;

        $this->pdf->_out(sprintf(
            'q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm',
            $c,$s,-$s,$c,$cx,$cy,-$cx,-$cy));
    }
    } 

}
header('Content-type: application/pdf');
//header('Content-Disposition: attachment; filename="downloaded.pdf"');
WaterMark::applyAndSpit('C:\xampp\htdocs\tst\test0.pdf','C:\xampp\htdocs\tst\output0.pdf');

Когда я загружаю PDF, который имеет более 2, все страницы объединяются в одну страницу. Я прикрепил изображение в этом посте.enter image description here

Благодарю.

@vascowhite Любая идея о том, как справиться с этим? Mr A
@MrA я отправил в github. Не могли бы вы, пожалуйста, посмотрите этоchinmay235.github.io/php-pdf-watermark Chinmay235
Вы видели это?setasign.de/products/pdf-php-solutions/setapdf-stamper vascowhite
Не совсем, но я бы начал с проверки того, что вставляется. Похоже, вся страница повернута. Извините, но у меня нет большого опыта работы с fpdf. Я использовал это, но только для очень простых вещей. Если у меня будет возможность поиграть с ним позже сегодня, я посмотрю, что смогу найти. Удачи. vascowhite

Ваш Ответ

2   ответа
2

что у FPDF есть некоторые подводные камни, с которыми сталкиваются несколько человек. Для меня я также заметил, что водяной знак отображается только на первой странице в некоторых экземплярах браузера, а также открывается через Adobe Acrobat (Acrobat X Pro).

Вместо этого я переключился на использование TCPDF, что решило множество проблем, включая:

No errors when setting angles Having ability to set transparency Custom fonts Updated Feature: Updating the text

Чтобы использовать пользовательские шрифты, просто раскомментируйте блок пользовательских шрифтов ниже (http://www.tcpdf.org/fonts.php).

Также, последнее замечание, стандартный пакет FPDI поддерживает только PDF версию 1.4. Поэтому, если вы импортируете какие-либо PDF-файлы выше этого уровня, импорт не будет работать и взорвется. Вам нужно будет купить коммерческую версию (https://www.setasign.com/products/fpdi-pdf-parser/details/), или просто сохраните ваши PDF-файлы в версии 1.4, вот что мы сделали.

Вот мой обновленный код:

require_once(APPPATH . 'third_party/tcpdf/tcpdf.php');
require_once(APPPATH . 'third_party/fpdi/fpdi.php');

class WatermarkerTCPDF extends FPDI {
    public $pdf, $file, $newFile,
            $wmText = "STACKOVERFLOW",
            $fontsize = 24,
            $fontfamily = 'ptsansnarrow400';

    /** $file and $newFile have to include the full path. */
    public function __construct($file = null, $newFile = null) {
        $this->pdf = new FPDI();
        //custom fonts
        //$this->fontfamily = $this->pdf->addTTFfont(APPPATH . 'third_party/tcpdf/ttf/ptsansnarrow400.ttf', 'TrueTypeUnicode', '');
        if (!empty($file)) {
            $this->file = $file;
        }
        if (!empty($newFile)) {
            $this->newFile = $newFile;
        }
    }

    /** $file and $newFile have to include the full path. */
    public static function applyAndSpit($file, $newFile = null) {
        $wm = new Watermarker($file, $newFile);

        if ($wm->isWaterMarked())
            return $wm->spitWaterMarked();
        else {
            $wm->doWaterMark();
            return $wm->spitWaterMarked();
        }
    }

    /** @todo Make the text nicer and add to all pages */
    public function doWaterMark() {
        $currentFile = $this->file;
        $newFile = $this->newFile;

        $pagecount = $this->pdf->setSourceFile($currentFile);

        for ($i = 1; $i <= $pagecount; $i++) {
            $tplidx = $this->pdf->importPage($i);
            $specs = $this->pdf->getTemplateSize($tplidx);
            $this->pdf->SetPrintHeader(false);
            $this->pdf->SetPrintFooter(false);
            $this->pdf->addPage($specs['h'] > $specs['w'] ? 'P' : 'L');
            $this->pdf->useTemplate($tplidx, null, null, 0, 0, true);

            // now write some text above the imported page
            $this->pdf->SetFont($this->fontfamily, '', $this->fontsize);
            $this->pdf->SetTextColor(204, 204, 204);
            //$this->pdf->SetXY($specs['w']/2, $specs['h']/2);
            $_x = ($specs['w']/2) - ($this->pdf->GetStringWidth($this->wmText, $this->fontfamily, '', $this->fontsize)/2.8);
            $_y = $specs['h']/2;
            $this->pdf->SetXY($_x, $_y);
            //$this->pdf->SetXY(0, 0);
            $this->pdf->setAlpha(0.3);
            $this->_rotate(45, 100, 100);
            $this->pdf->Write(0, $this->wmText);
            //$this->pdf->writeHTMLCell($w=0, $h=0, $x='', $y='', $this->wmText, $border=0, $ln=1, $fill=0, $reseth=true, $align='', $autopadding=true);
        }

        if (empty($newFile)) {
            header('Content-Type: application/pdf');
            $this->pdf->Output();
        } else {
            $this->pdf->Output($newFile, 'F');
        }
    }

    public function isWaterMarked() {
        //return (file_exists($this->newFile));
        $_file = $this->newFile;
        $file = file_get_contents($_file);
        force_download($file);
    }

    public function spitWaterMarked() {
        $_file = $this->newFile;
        $file = file_get_contents($_file);
        force_download($file);
        //return readfile($this->newFile);
    }

    protected function _rotate($angle, $x = -1, $y = -1) {
        if ($x == -1)
            $x = $this->pdf->x;
        if ($y == -1)
            $y = $this->pdf->y;
        //if ($this->pdf->angle != 0)
            //$this->pdf->_out('Q');
        $this->pdf->angle = $angle;

        if ($angle != 0) {
            $angle*=M_PI / 180;
            $c = cos($angle);
            $s = sin($angle);
            $cx = $x * $this->pdf->k;
            $cy = ($this->pdf->h - $y) * $this->pdf->k;

            $this->pdf->_out(sprintf(
                            'q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm', $c, $s, -$s, $c, $cx, $cy, -$cx, -$cy));
        }
    }

    public function wmText($text = null)
    {
        $total = 20;
        if (!empty($text)) {
            $this->wmText = '';
            for ($i = 0; $i < $total; $i++) {
                $this->wmText .= ' ' . $text;
            }

        }

        return $this;
    }
}

Чтобы использовать это, просто:

try {
    //this is for CodeIgniter
    $this->load->library('WatermarkerTCPDF');

    //if your using it as a standard class in vanilla PHP just do:
    //require_once('PATH_TO_LIBRARY/WatermarkerPDF.php');

    //If you want to output the PDF to another file, you can supply
    //a second parameter: new WatermarkerTCPDF($file_path, $new_file_path);
    //just remember, the full path is required
    $watermark = new WatermarkerTCPDF($file_path);
    $watermark->wmText($this->session->userdata('email'));
    $watermark->doWaterMark();
} catch (Exception $e) {
    exit($e->getMessage());
}

В любом случае, надеюсь, это когда-нибудь кому-нибудь поможет!

Помог мне. Вы спасатель жизни!
Помог мне. Вы спасатель жизни! & # XB2; знак равно
@yogibear, useTemplate ($ tplidx, null, null, 0, 0, true); не работает со значениями 0 для ширины и высоты, поэтому мне пришлось передавать динамически полученные значения ширины и высоты с "false" в качестве последнего аргумента метода useTemplate (). Для меня это работало следующим образом: $ this-> pdf-> useTemplate ($ tplidx, null, null, $ specs ['width'], $ specs ['height & apos;], false);
Большая помощь! Хотя мне нужно было изменить использование fontFamily, пришлось удалить SetPrintHeader () и SetPrintFooter (), потому что они больше не включены в TCPDF.
7

аботать, изменитеdoWatermark() метод к этому: -

public function doWaterMark()
{
    $currentFile = $this->file;
    $newFile = $this->newFile;

    $pagecount = $this->pdf->setSourceFile($currentFile);

    for($i = 1; $i <= $pagecount; $i++){
        $this->pdf->addPage();//<- moved from outside loop
        $tplidx = $this->pdf->importPage($i);
        $this->pdf->useTemplate($tplidx, 10, 10, 100);
        // now write some text above the imported page
        $this->pdf->SetFont('Arial', 'I', 40);
        $this->pdf->SetTextColor(255,0,0);
        $this->pdf->SetXY(25, 135);
        $this->_rotate(55);
        $this->pdf->Write(0, $this->wmText);
        $this->_rotate(0);//<-added
    }

    $this->pdf->Output($newFile, 'F');
}

Я сдвинул линию$this->pdf->addPage(); в цикл, так как в противном случае все выводится на одну страницу. Я также добавил$this->_rotate(0); вернуть документ в вертикальное положение перед сохранением. Довольно просто на самом деле. Я прокомментировал измененные строки для вас.

Я протестировал его на 32-страничном PDF, и он, кажется, работал нормально.

Кто-нибудь не заметил, что на Acrobat Reader для ПК, если текст находится под углом, то весь PDF-файл выходит из строя. У кого-нибудь есть обходной путь для этого? Смотрите мой вопросstackoverflow.com/questions/13069104/…
Не уверен, если кто-то все еще заинтересован, но я достиг эффекта прозрачности, который я хотел, используя следующий подход:$this->pdf->SetAlpha(0.1); $this->pdf->StartTransform(); $this->pdf->Rotate(45, $watermarkXCord, $watermarkYCord); $this->pdf->SetFont("", "", 120); $this->pdf->Text($watermarkXCord, $watermarkYCord, $this->watermarkAttribute); $this->pdf->StopTransform(); $this->pdf->SetAlpha(1);
Любая идея о том, как установить прозрачность? Я изменил значения, подобные этому, но не получил никакого результата.fpdf.org/en/script/script9.php Mr A
Хорошо. Этот трюк не сработает, если PDF - это отсканированная копия. Mr A
Это не прозрачно, просто бледный цвет, и они обманывают, сначала вставляя водяной знак, а затем помещая текст страницы поверх этого.fpdf.org/en/script/watermark.pdf

Похожие вопросы