Вопрос

Я создаю счет-фактуру в формате PDF с помощью fpdf.

Некоторые счета-фактуры содержат много товаров, и детали должны быть перенесены на вторую страницу.Однако мне нужно, чтобы общая сумма и другие детали отображались на первой странице.

Прямо сейчас, если я смогу добавить новую страницу, подобную этой:$pdf->addPage();

Но это помещает все на вторую страницу, независимо от того, что следует за этим утверждением.

Кажется, нет способа указать страницу ни для методов write, ни для методов cell.

Рендеринг и вычисления немного сложны, поэтому я не хочу сохранять их во временный массив и отображать после полного рендеринга первой страницы.

Спасибо.

Это было полезно?

Решение

if(!empty($this->replace) && !empty($this->replacement)){
    $this->pages[$n]=str_replace($this->replace,$this->replacement,$this->pages[$n]);
}

Я добавил этот код в класс fpdf в _putpages () прямо под строкой содержимого / Страница 2851

Пример после добавления выше к коду:

$pdf->replace = array("{paid_msg}","{balance}");
$pdf->replacement = array("Paid","0.00");

Это может быть строка или массив.

Другие советы

У меня была очень похожая проблема, и я пошел дальше и просто добавил функцию в класс:

function SetPage($num) {
    $this->page = $num;
}

Это делает буквально то, что вы ожидаете.Но, когда вы пытаетесь вернуться на следующую страницу, вам нужно либо установить это явно, либо добавить функциональность Cell().Вот где он добавляет страницу:

    if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())

Это проверяет наличие AcceptPageBreak и, очевидно, является ли высота страницы меньше того места, где мы окажемся в конечном итоге, если останемся на странице.Что я сделал, так это добавил сюда условие, чтобы проверить, есть ли еще одна страница ниже.Если бы это было так, вместо ТОГО, чтобы ДОБАВЛЯТЬ новую страницу, я пошел дальше и просто установил букву Y на поле и использовал описанную выше функцию для посещения этой страницы.Как таковой:

if ($this->page < count($this->pages)) {
        $this->SetPage(($this->page)+1);
        $this->y = .5;
    }

Если вам неудобно возиться с FPDF, возможно, это не для вас, но после решения этой проблемы я понял, что на самом деле в скрипте была очень простая навигация и оставалось много возможностей для простых улучшений.Обратите внимание, что вместо проверки наличия другой страницы выше, вы также могли бы добавить переменную, которую вы могли бы вызывать, которая временно сообщала бы скрипту, что вместо добавления страницы вы просто переходите к следующему.

FPDF не позволяет вам вернуться на предыдущую страницу. Как только вы закончите со страницей - либо вызовом AddPage (), либо исчерпанием свободного места, когда SetAutoPageBreak () включен, - все готово.

Обходной путь - сгенерировать документ без итогов, записать его во временный файл и загрузить обратно (с помощью FPDI: http://www.setasign.de/products/pdf-php-solutions/fpdi/ ) и добавьте итоговое значение в правильном месте.

Здесь есть несколько умных решений, но я не рекомендую этот обман, потому что он идет вразрез с базовой моделью FPDF и рано или поздно, вероятно, вызовет другие проблемы в будущем.

Программирование уже достаточно сложное!

Итак, отделите модель счета-фактуры или чего-то еще от презентации. Построить всю модель. Затем выведите презентацию (в данном случае PDF).

Я нашел очень подходящий метод * str_replace * из-за необходимости писать «n из m страниц». Сначала записали n-число, как обычно, когда я создавал каждую страницу, и, наконец, заменили шифр m на $ pdf-> gt; pages [$ i] постранично.

Я столкнулся с этой проблемой, имея макет из двух столбцов, где один столбец мог быть настолько большим, что охватывал бы следующую страницу. Я хотел установить позицию Y обратно в ту же позицию Y, что и в первом столбце, чтобы они были выровнены относительно друг друга, но также продолжил документ под самым большим из двух столбцов.

Моим решением было записать " вертикальное положение " документа, который включает номер страницы ( $ pdf- > PageNo () ) и позицию Y ( $ pdf- > GetY () ).

Вам нужно хранить две разные вертикальные позиции. Сначала сохраните " Начальную точку " где вы начнете свой второй столбец. Во-вторых, сохраните «Самую большую точку». который дальше всего вниз по документу. Самая большая точка была хитрой, потому что вы не можете смотреть только на номер страницы или значение Y, вы должны смотреть на оба.

Я создал эти три метода, чтобы помочь мне.

Это решение не включает X-позицию в примере.

public function GetVerticalPosition() {
  // Include page and Y position of the document
  return array(
    'page' => $this->PageNo(),
    'y' => $this->GetY(),
  );
}

public function SetVerticalPosition( $pos ) {
  // Set the page and Y position of the document
  $this->page = $pos['page'];
  $this->SetY( $pos['y'] );
}

public function FurthestVerticalPosition( $aPos, $bPos = null ) {
  if ( $bPos === null ) $bPos = $this->GetVerticalPosition();

  // Returns the "furthest" vertical position between two points, based on page and Y position
  if ( 
    ($aPos['page'] > $bPos['page']) // Furthest position is located on another page
    ||
    ($aPos['page'] == $bPos['page'] && $aPos['y'] > $bPos['y'] ) // Furthest position is within the same page, but further down
  ) {
    return $aPos;
  }else{
    return $bPos;
  }
}

Использование довольно просто. Перед тем, как нарисовать столбцы переменной высоты, вам нужно захватить начальную позицию и начать собирать максимальную позицию.

$startPos = $this->GetVerticalPosition();
$furthestPos = $this->GetVerticalPosition();

После рендеринга каждой ячейки, перед рендерингом другой ячейки на том же уровне вы хотите обновить самую дальнюю позицию (при необходимости), а затем вернуться в исходную позицию.

// Returns the furthest of the two possibilites
$furthestPos = $this->FurthestVerticalPosition( $this->GetVerticalPosition(), $furthestPos );
$this->SetVerticalPosition( $startPos );

Когда вы закончите рендеринг столбцов, установите для документа максимальное расстояние, которое вы записали.

$this->SetVerticalPosition( $furthestPos );

Теперь ваши столбцы правильно выровнены, а указатель документа расположен сразу после самого дальнего отрисованного столбца.

У меня была та же проблема, и я переопределил несколько методов класса FPDF и смог исправить это довольно простым способом. Для того, чтобы перемещаться по страницам вперед и назад, вам просто нужно изменить атрибут страницы объекта FPDF. Однако, как только вы вернетесь на страницу, перейдя на следующую страницу, вы в конечном итоге добавите новую страницу вместо того, чтобы перейти к уже существующей. Чтобы решить эту проблему, я создал логическое значение add_new_page и использовал его в своем переписанном методе accept_page_break, чтобы узнать, создавать ли новую страницу или переходить к уже существующей.

def prev_page(self):
    self.page -= 1
    self.add_new_page = False

def next_page(self):
    self.page += 1

def accept_page_break(self):
    "Accept automatic page break or not"
    if self.add_page:
        return self.auto_page_break
    else:
        self.page += 1
        self.add_new_page = True

Просто "взлом", но данные должны быть упорядочены по номеру страницы (не очень сложно ^ ^)

Вставьте " для цикла " размещение данных что-то вроде:

// ensure we are on the good page, but fields HAVE TO be ordered by page number
while($this->fpdf->PageNo() != $myData->getPage()){
    $this->fpdf->AddPage();
}

И все готово! Не нужно менять FPDF: D

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top