问题
I am trying to create pages of incrementing labels that include barcodes. I can get a barcode into a PDF, and I can get it superimposed on other content in the PDF (see below). But I can't figure out how to assign a barcode to a certain page of a pdf using something maybe like
Zend_Barcode::factory('code39', 'pdf',
$barcodeOptions, $rendererOptions)->setResource($page)->draw();
or
$page = Zend_Barcode::factory('code39', 'pdf', $barcodeOptions,
$rendererOptions)->setResource($pdf)->draw();
Both of the above snippets cause errors when set in the context of my larger code. Further down is code that renders with no errors, but doesn't give me what I need.
This question is identical to Zend Framework Render Barcodes Into PDF Pages, which never reached a working answer from what I can see.
First, to get this to work, I copied the Zend version 1.11 Barcode library into my Zend version 1.7.2 library folder. I also copied a free non-monospaced font into my application/library as the code shows.
I can create a multi-page PDF of labels. And I can put a barcode in a PDF. What I can't do is put barcodes on multiple pages. I'll show what I am doing, and hopefully you can tell me what I am doing wrong or need to do.
First I have this little snippet that puts a barcode in a PDF:
// A font path is mandatory for Barcode Pdf output.
// This application defines ROOT_DIR in index.php. Others may define APPLICATION_PATH.
// Monospaced fonts apparently don't work here.
$barcodeOptions = array(
'text' => '11111',
'font' => ROOT_DIR . '/library/Rbs/Barcode/FreeSerif.ttf'
);
$rendererOptions = array(
'topOffset' => 50,
'leftOffset' => 50
);
Zend_Barcode::factory('code39', 'pdf',
$barcodeOptions, $rendererOptions)->setResource($pdf)->draw();
Then I have this (long) code that creates labels. I've commented below near the bottom the two main places I have experimented putting the barcode, but the core problem seems to be that I don't know how to put a barcode on a certain page of a PDF:
public function labelsAction()
{
$request['starting_label_number'] = '100001';
$request['label_count'] = 32;
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$filename= 'files/inventory_labels.pdf';
$form['units_name'] = 'inches';
$form['units_factor'] = 72;
$form['margin_bottom'] = 0.5;
$form['margin_left'] = 0.19;
$form['label_width'] = 2.625;
$form['label_height'] = 1.0;
$form['label_spacing_column'] = 0.125;
$form['label_margin'] = 0.1;
$form['label_column_count'] = 3;
$form['label_row_count'] = 10;
try
{
// create PDF
$pdf = new Zend_Pdf();
// define font resource
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES_ROMAN);
$total_pages = ceil($request['label_count'] / ($form['label_column_count'] * $form['label_row_count']));
$current_label_number = $request['starting_label_number'];
// Create each page
for ($page_number = 1; $page_number <= $total_pages; $page_number++)
{
// create A4 page
$page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_LETTER);
// write text to page
// Fill up each page with labels or blanks
for ($row = 1; $row <= $form['label_row_count']; $row++)
{
for ($column = 1; $column <= $form['label_column_count']; $column++)
{
if ($current_label_number - $request['starting_label_number'] < $request['label_count'])
{
$label_center_y =
(
$form['margin_bottom']
+ ($form['label_row_count'] - $row + 0.5) * $form['label_height']
) * $form['units_factor'];
$label_center_x =
(
$form['margin_left']
+ ($column - 0.5) * $form['label_width']
+ ($column - 1) * $form['label_spacing_column']
) * $form['units_factor'];
// Get our bearings $xleft, $ybottom, $xright, $ytop, $filltype
$page->drawRectangle(
$label_center_x - $form['label_width'] * $form['units_factor'] / 2,
$label_center_y - $form['label_height'] * $form['units_factor'] / 2,
$label_center_x + $form['label_width'] * $form['units_factor'] / 2,
$label_center_y + $form['label_height'] * $form['units_factor'] / 2,
Zend_Pdf_Page::SHAPE_DRAW_STROKE
);
// define image resource
$image = Zend_Pdf_Image::imageWithPath('images/new/logo.jpg');
// write image to page $xleft, $ybottom, $xright, $ytop
$image_width = 125;
$image_height = 30;
$image_y_offset = 13;
$page->drawImage(
$image,
$label_center_x - $image_width / 2,
$label_center_y - $image_height / 2 + $image_y_offset,
$label_center_x + $image_width / 2,
$label_center_y + $image_height / 2 + $image_y_offset
);
$text_width = 108;
$page->setFont($font, 10)
->drawText('www.pristineauction.com', $label_center_x - $text_width / 2, $label_center_y - 10);
$text_width = 68;
$page->setFont($font, 22)
->drawText($current_label_number, $label_center_x - $text_width / 2, $label_center_y - 32);
$current_label_number += 1;
}
}
}
/* If I insert the barcode creator here inside the label loop, I get a barcode all by itself on the first PDF page, with labels following on subsequent pages. Not bad, but not right. */
// add page to document
$pdf->pages[] = $page;
}
/* If I insert the barcode creator here outside the label loop, I get a barcode superimposed on the first PDF page. Not bad, but not in page loop, and not repeating. */
// save as file
$pdf->save($filename);
$this->_redirect('/' . $filename);
} catch (Zend_Pdf_Exception $e) {
die ('PDF error: ' . $e->getMessage());
} catch (Exception $e) {
die ('Application error: ' . $e->getMessage());
}
}
回答1:
Well, I found the answer, thanks to Javier Bracero at http://javierbracero.blogspot.com/2012/01/zend-generate-pdf-including-list-of.html
You can supply page index as an argument! Very nice to finally know that.
The good parts:
// Create Pdf definition
$pdf = new Zend_Pdf();
// Define font resource for Pdf library
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES_ROMAN);
// Must set a TTF for Barcode library
// This application defines ROOT_DIR in index.php. Others may define APPLICATION_PATH.
Zend_Barcode::setBarcodeFont(ROOT_DIR . '/library/Rbs/Barcode/FreeSerif.ttf');
// Create the Pdf library elements for each page and add it to the document
// before printing the Barcode elements onto that page
for ($page_index = 0; $page_index <= $last_page_index; $page_index++)
{
// create a new Pdf page
$page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_LETTER);
// write Pdf elements to the page
// add page to document
$pdf->pages[] = $page;
}
// Add barcodes to each page after it is added.
for ($page_index = 0; $page_index <= $last_page_index; $page_index++)
{
$barcodeOptions = array(
'text' => $current_label_number
);
$rendererOptions = array(
'topOffset' => $label_center_y + 3,
'leftOffset' => $label_center_x + 12
);
Zend_Barcode::factory('code39', 'pdf',
$barcodeOptions, $rendererOptions)->setResource($pdf, $page_index)->draw();
$current_label_number += 1;
}
// save as file
$pdf->save($filename);
The whole label maker:
// By Tom Haws 2012-10-03
// Prints labels with barcodes to pdf
public function labelsAction()
{
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$request['start_number'] = max(1, $this->_request->getParam('start-number'));
$request['label_count'] = $this->_request->getParam('label-count');
$inventory_number = $request['start_number'];
$filename= 'files/inventory_labels.pdf';
$form['units_name'] = 'inches';
$form['units_factor'] = 72;
$form['margin_top'] = 0.5;
$form['margin_bottom'] = 0.5;
$form['margin_left'] = 0.19;
$form['label_width'] = 2.625;
$form['label_height'] = 1.0;
$form['label_spacing_column'] = 0.125;
$form['label_margin'] = 0.1;
$form['label_column_count'] = 3;
$form['label_row_count'] = 10;
$last_page_index = ceil($request['label_count'] / ($form['label_column_count'] * $form['label_row_count'])) - 1;
$current_label_number = $request['start_number'];
try
{
// Create PDF
$pdf = new Zend_Pdf();
// Define font resource for Pdf library
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES_ROMAN);
// Must set a TTF for Barcode library
Zend_Barcode::setBarcodeFont(ROOT_DIR . '/library/Rbs/Barcode/FreeSerif.ttf');
// Create the Pdf library elements for each page and add it to the document
// before printing the Barcode elements onto that page
for ($page_index = 0; $page_index <= $last_page_index; $page_index++)
{
// create the new Pdf page
$page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_LETTER);
// write Pdf elements to the page
// Fill up each page with labels or blanks
for ($row = 1; $row <= $form['label_row_count']; $row++)
{
for ($column = 1; $column <= $form['label_column_count']; $column++)
{
if ($current_label_number - $request['start_number'] < $request['label_count'])
{
// Note that Pdf library uses a coordinate system with origin at bottom left
$label_center_y =
(
$form['margin_bottom']
+ ($form['label_row_count'] - $row + 0.5) * $form['label_height']
) * $form['units_factor'];
$label_center_x =
(
$form['margin_left']
+ ($column - 0.5) * $form['label_width']
+ ($column - 1) * $form['label_spacing_column']
) * $form['units_factor'];
// Draw a design guidance frame for each label.
// $xleft, $ybottom, $xright, $ytop, $filltype
/*
$page->drawRectangle(
$label_center_x - $form['label_width'] * $form['units_factor'] / 2,
$label_center_y - $form['label_height'] * $form['units_factor'] / 2,
$label_center_x + $form['label_width'] * $form['units_factor'] / 2,
$label_center_y + $form['label_height'] * $form['units_factor'] / 2,
Zend_Pdf_Page::SHAPE_DRAW_STROKE
); */
// define image resource
$image = Zend_Pdf_Image::imageWithPath('images/new/logo.jpg');
// write image to page $xleft, $ybottom, $xright, $ytop
$image_width = 125;
$image_height = 30;
$image_y_offset = 20;
$page->drawImage(
$image,
$label_center_x - $image_width / 2,
$label_center_y - $image_height / 2 + $image_y_offset,
$label_center_x + $image_width / 2,
$label_center_y + $image_height / 2 + $image_y_offset
);
$text_width = 108;
$page->setFont($font, 10)
->drawText('www.pristineauction.com', $label_center_x - $text_width / 2, $label_center_y - 1);
$text_width = 68;
$page->setFont($font, 22)
->drawText($current_label_number, $label_center_x - 72, $label_center_y - 25);
$current_label_number += 1;
}
}
}
// add page to document
$pdf->pages[] = $page;
}
// Add barcodes to pages of document.
$current_label_number = $request['start_number'];
for ($page_index = 0; $page_index <= $last_page_index; $page_index++)
{
for ($row = 1; $row <= $form['label_row_count']; $row++)
{
for ($column = 1; $column <= $form['label_column_count']; $column++)
{
// Note that barcodes use a coordinate system with origin at top left
$label_center_y =
(
$form['margin_top']
+ ($row - 0.5) * $form['label_height']
) * $form['units_factor'];
$label_center_x =
(
$form['margin_left']
+ ($column - 0.5) * $form['label_width']
+ ($column - 1) * $form['label_spacing_column']
) * $form['units_factor'];
// A font path is mandatory for Barcode Pdf output.
// This application defines ROOT_DIR in index.php. Others may define APPLICATION_PATH.
$barcodeOptions = array(
'text' => $current_label_number
);
$rendererOptions = array(
'topOffset' => $label_center_y + 3,
'leftOffset' => $label_center_x + 12
);
Zend_Barcode::factory('code39', 'pdf',
$barcodeOptions, $rendererOptions)->setResource($pdf, $page_index)->draw();
$current_label_number += 1;
}
}
}
// save as file
$pdf->save($filename);
$this->_redirect('/' . $filename);
} catch (Zend_Pdf_Exception $e) {
die ('PDF error: ' . $e->getMessage());
} catch (Exception $e) {
die ('Application error: ' . $e->getMessage());
}
}
来源:https://stackoverflow.com/questions/12717901/zend-framework-render-barcodes-into-multiple-pdf-pages-with-other-content