-
Notifications
You must be signed in to change notification settings - Fork 0
/
PdfLabel.php
289 lines (261 loc) · 7.7 KB
/
PdfLabel.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
<?php
/**
* PDFLabel
*
* @link https://github.com/WeeSee/yii2-pdflabel
* @copyright Copyright (c) 2018 WeeSee
* @license https://github.com/WeeSee/yii2-pdflabel/blob/master/LICENSE
*/
namespace weesee\pdflabel;
use yii\base\Component;
use yii\helpers\Html;
use weesee\pdflabel\TCPDFLabel;
/**
* Ths class PdfLabel is a Yii2 Component to
* print labes on PDF. There are multipe label
* formats supported in letter and A4 format,
* e.g. Avery 5160.
*
* @author WeeSee <[email protected]>
*/
class PdfLabel extends Component
{
/**
* Label name type to print labels on
* @var string
*/
public $labelName;
/**
* List of label formats extending Uskur/PdfLabel
* The key is the label name
* Use getLabelName() to get all labels
*
* @var array
*/
const LABEL_FORMATS = [
// define your own labels here
/*
'Avery 9999' => [
'paper-size' => 'A4',
'unit' => 'mm',
'marginLeft' => 1.762,
'marginTop' => 10.7,
'NX' => 3,
'NY' => 10,
'SpaceX' => 3.175,
'SpaceY' => 0,
'width' => 66.675,
'height' => 25.4
],
*/
];
/**
* Output destination:
* for details, see https://github.com/tecnickcom/TCPDF/blob/95c5938aafe4b20df1454dbddb3e5005c0b26f64/tcpdf.php#L7548
* @var string
*/
public $output = self::OUTPUT_BROWSER_INLINE;
const OUTPUT_BROWSER_INLINE = 'I';
const OUTPUT_BROWSER_DOWNLOAD = 'D';
const OUTPUT_SAVE_FILE = 'F';
const OUTPUT_STRING = 'S';
const OUTPUT_SAVE_FILE_AND_BROWSER_INLINE = 'FI';
const OUTPUT_SAVE_FILE_AND_BROWSER_DOWNLOAD = 'FD';
const OUTPUT_BASE64 = 'E';
/*
* Filename is file is downloaded or saved
* @var string
*/
public $downloadFilename = "output.pdf";
/**
* Font for label content
* For default fonts see https://tcpdf.org/docs/fonts/
* @var string
*/
public $font = 'courier';
/**
* Font size
* @var integer
*/
public $size = 10;
/**
* The number of empty labels to start with
* @var integer
*/
public $offsetEmptyLabels;
/**
* DataProvider for the models to print on labels.
* This property is required.
* @var \yii\data\DataProviderInterface
*/
public $dataProvider;
/**
* @var callable Closure to render one cell label
* The signature of the function should be the following:
* `function ($model, $key, $index)`.
* Where `$model`, `$key`, and `$index` refer to the model,
* key and index of the label currently being rendered
*/
public $renderLabel;
/**
* @var string creator as meta data in PDF document
* false set Yii2 application name
*/
public $creator = false;
/**
* @param bool $asHtml print $content with HTML tags
*/
public $asHtml = false;
/**
* @var string author as meta data in PDF document
*/
public $author = 'weesee';
/**
* @var string title as meta data in PDF document
*/
public $title = 'Labels';
/**
* @var string subject as meta data in PDF document
*/
public $subject = 'Labels';
/**
* @var string keywords as meta data in PDF document
*/
public $keywords = '';
/**
* @var UskurPdfLabel Handle to access PfdfLabel
*/
protected $pdfLabel;
/**
* @var bool Print border to tes new label formats
*/
public $border = false;
/**
* Initialize the class with options from user
* The options are set using Yii2 init mechanism for Components
* Options:
* - labelType: string (e.g. "5160") or array with format spec
* - font, size
* - author, creator, title, keywords, subject:
* - offsetEmptyLabels: integer. How many labels to skip at the beginning
*/
public function init()
{
parent::init();
// user provides a custom label type
if (is_array($this->labelName))
$format = $this->labelName;
// a lable type from this class?
elseif (isset(self::LABEL_FORMATS[$this->labelName]))
$format = self::LABEL_FORMATS[$this->labelName];
// or a label type from PdfLabel class?
elseif (isset(TCPDFLabel::LABELS[$this->labelName]))
$format = $this->labelName;
else
throw new \yii\base\InvalidConfigException('The "labelType" property must be set.');
if ($this->dataProvider === null) {
throw new \yii\base\InvalidConfigException('The "dataProvider" property must be set.');
}
if (!is_callable($this->renderLabel)) {
throw new \yii\base\InvalidConfigException('The "renderLabel" property must be set.');
}
$this->pdfLabel = new TCPDFLabel($format);
$this->pdfLabel->AddPage();
$this->pdfLabel->SetFont($this->font, '', $this->size);
$this->pdfLabel->SetCreator($this->creator?:\Yii::$app->name);
$this->pdfLabel->SetAuthor($this->author);
$this->pdfLabel->SetTitle($this->title);
$this->pdfLabel->SetSubject($this->subject);
$this->pdfLabel->SetKeywords($this->keywords);
for ($i=$this->offsetEmptyLabels;$i>0;$i--)
$this->addLabel('');
}
/**
* Get all label formats
* @param string $pageFormat the page format ('*','A4','letter')
* @return array label format list
*/
public static function getLabelNames($pageFormat="A4")
{
$labelNames = [];
// Label names for PdfLabel-Library
$pdfLabelNames = [
'3422' => 'Avery 3422 (A4)',
'5160' => 'Avery 5160 (letter)',
'5161' => 'Avery 5161 (letter)',
'5162' => 'Avery 5162 (letter)',
'5163' => 'Avery 5163 (letter)',
'5164' => 'Avery 5164 (letter)',
'L7161' => 'Avery L7161 (A4)',
'L7163' => 'Avery L7163 (A4)',
'8600' => '8600 (letter)',
'NewPrint4005' => '2x4 (A4)',
];
$allLabels = TCPDFLabel::LABELS + self::LABEL_FORMATS;
foreach($allLabels as $name => $format) {
if (!preg_match("/$pageFormat/",$format['paper-size']))
continue;
$newName = is_array($format) ? $name : $pdfLabelNames[$name];
$labelNames[$name] = $newName;
}
return $labelNames;
}
/**
* Adds a new label
* @param string $content the content for the label. Lines can be
* separated by \n
* IMPORTANT: The HTML must be well formatted - try to clean-up it using an
* application like HTML-Tidy before submitting. Supported tags are: a, b,
* blockquote, br, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6,
* hr, i, img, li, ol, p, pre, small, span, strong, sub, sup, table,
* tcpdf, td, th, thead, tr, tt, u, ul
* NOTE: all the HTML attributes must be enclosed in double-quote.
* @return object to concantenate as addlabel(...)->addLabel(...)
*/
public function addLabel($content)
{
if ($this->asHtml)
$this->pdfLabel->addExtendedHtmlLabel($content,$this->border);
else
$this->pdfLabel->addExtendedLabel($content,$this->border);
return $this;
}
/**
* Adds labels for all models from given dataProvider
*/
protected function renderModels()
{
if ($this->dataProvider->count > 0) {
$models = array_values($this->dataProvider->getModels());
$keys = $this->dataProvider->getKeys();
foreach ($models as $index => $model) {
$key = $keys[$index];
if (is_callable($this->renderLabel)) {
$label = call_user_func($this->renderLabel, $model, $key, $index);
} else
$label = "";
$this->pdfLabel->addLabel($label);
}
}
}
/**
* Renders the page with the all labels
* @param mixed $model the data model
* @param mixed $key the key associated with the data model
* @param int $index the zero-based index of the data model among the models array returned by [[GridView::dataProvider]].
* @return string the rendered pdf as response object
*/
public function render()
{
if ($this->dataProvider)
$this->renderModels();
return \Yii::$app->response->sendContentAsFile(
$this->pdfLabel->Output('',self::OUTPUT_STRING),
$this->downloadFilename,
[
'inline' => true,
'mimeType' => 'application/pdf',
]
);
}
}