forked from wheelibin/SharpPDFLabel
-
Notifications
You must be signed in to change notification settings - Fork 10
/
CustomLabelCreator.cs
220 lines (173 loc) · 7.21 KB
/
CustomLabelCreator.cs
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
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Collections.Generic;
using System.IO;
namespace SharpPDFLabel
{
/// <summary>
/// Contains the labels/PDF creation logic
/// </summary>
public class CustomLabelCreator
{
private LabelDefinition _labelDefinition;
private List<Label> _labels;
/// <summary>
/// Useful for debugging the formatting if needed
/// </summary>
public bool IncludeLabelBorders { get; set; }
public CustomLabelCreator(LabelDefinition labelDefinition)
{
FontFactory.RegisterDirectories(); //Register all local fonts
_labelDefinition = labelDefinition;
_labels = new List<Label>();
IncludeLabelBorders = false;
}
/// <summary>
/// Add a label to the collection
/// </summary>
/// <param name="label"></param>
public void AddLabel(Label label)
{
_labels.Add(label);
}
/// <summary>
/// Create the PDF using the defined page size, label type and content provided
/// Ensure you have added something first using either AddImage() or AddText()
/// </summary>
/// <returns></returns>
public Stream CreatePDF()
{
//Get the itext page size
Rectangle pageSize;
switch (_labelDefinition.PageSize) {
case Enums.PageSize.A4:
pageSize = iTextSharp.text.PageSize.A4;
break;
default:
pageSize = iTextSharp.text.PageSize.A4;
break;
}
//Create a new iText document object, define the paper size and the margins required
var doc = new Document(pageSize,
_labelDefinition.PageMarginLeft,
_labelDefinition.PageMarginRight,
_labelDefinition.PageMarginTop,
_labelDefinition.PageMarginBottom);
//Create a stream to write the PDF to
var output = new MemoryStream();
//Creates the document tells the PdfWriter to use the output stream when Document.Close() is called
var writer = PdfWriter.GetInstance(doc, output);
//Ensure stream isn't closed when done - we need to return it
writer.CloseStream = false;
//Open the document to begin adding elements
doc.Open();
//Create a new table with label and gap columns
var numOfCols = _labelDefinition.LabelsPerRow + (_labelDefinition.LabelsPerRow - 1);
// var tbl = new PdfPTable(numOfCols);
//Build the column width array, even numbered index columns will be gap columns
var colWidths = new List<float>();
for (int i = 1; i <= numOfCols; i++) {
if (i % 2 > 0) {
colWidths.Add(_labelDefinition.Width);
} else {
//Even numbered columns are gap columns
colWidths.Add(_labelDefinition.HorizontalGapWidth);
}
}
/* The next 3 lines are the key to making SetWidthPercentage work */
/* "size" specifies the size of the page that equates to 100% - even though the values passed are absolute not relative?! */
/* (I will never get those 3 hours back) */
var w = iTextSharp.text.PageSize.A4.Width - (doc.LeftMargin + doc.RightMargin);
var h = iTextSharp.text.PageSize.A4.Height - (doc.TopMargin + doc.BottomMargin);
var size = new iTextSharp.text.Rectangle(w, h);
// loop over the labels
var rowNumber = 0;
var colNumber = 0;
PdfPTable tbl = null;
foreach (var label in _labels) {
if (rowNumber == 0) {
tbl = new PdfPTable(numOfCols);
tbl.SetWidthPercentage(colWidths.ToArray(), size);
rowNumber = 1; // so we start with row 1
doc.NewPage();
}
colNumber++; // so we start with col 1
// add the label cell.
var cell = FormatCell(label.GetLabelCell());
//Add to the row
tbl.AddCell(cell);
//Create a empty cell to use as a gap
if (colNumber < numOfCols) {
tbl.AddCell(CreateGapCell());
colNumber++; // increment for the gap row
}
//On all but the last row, after the last column, add a gap row if needed
if (colNumber == numOfCols && ((rowNumber) < _labelDefinition.LabelRowsPerPage && _labelDefinition.VerticalGapHeight > 0)) {
tbl.Rows.Add(CreateGapRow(numOfCols));
}
if (colNumber == numOfCols) {
// add the row to the table and re-initialize
tbl.CompleteRow();
rowNumber++;
colNumber = 0;
}
if (rowNumber > _labelDefinition.LabelRowsPerPage) {
//Add the table to the document
doc.Add(tbl);
rowNumber = 0;
colNumber = 0;
}
}
if (colNumber < numOfCols) {
// finish the row that was being built
while (colNumber < numOfCols) {
if (colNumber % 2 == 1) {
tbl.AddCell(CreateEmptyLabelCell());
} else {
tbl.AddCell(CreateGapCell());
}
colNumber++;
}
tbl.CompleteRow();
}
// make sure the last table gets added to the document
if (rowNumber > 0) {
//Add the table to the document
doc.Add(tbl);
}
//Close the document, writing to the stream we specified earlier
doc.Close();
//Set the stream back to position 0 so we can use it when it's returned
output.Position = 0;
return output;
}
private PdfPCell CreateEmptyLabelCell()
{
PdfPCell cell = new PdfPCell();
return FormatCell(cell);
}
private PdfPCell FormatCell(PdfPCell cell)
{
//Ensure our label height is adhered to
cell.FixedHeight = _labelDefinition.Height;
cell.Border = IncludeLabelBorders ? Rectangle.BOX : Rectangle.NO_BORDER;
return cell;
}
private PdfPCell CreateGapCell()
{
var cell = new PdfPCell {
FixedHeight = _labelDefinition.VerticalGapHeight,
Border = Rectangle.NO_BORDER
};
return cell;
}
private PdfPRow CreateGapRow(int numOfCols)
{
var cells = new List<PdfPCell>();
for (int i = 0; i < numOfCols; i++) {
cells.Add(CreateGapCell());
}
return new PdfPRow(cells.ToArray());
}
}
}