Line data Source code
1 : #include <QFile>
2 : #include <QTextStream>
3 : #include "utils/replacer.hpp"
4 : #include "convertertohtml.hpp"
5 : #include "cmath"
6 :
7 : namespace qtreports {
8 : namespace detail {
9 :
10 5 : ConverterToHTML::ConverterToHTML( const ReportPtr & report ) :
11 5 : m_report( report ) {}
12 :
13 5 : ConverterToHTML::~ConverterToHTML() {}
14 :
15 3 : bool ConverterToHTML::convert() {
16 3 : return createHTML();
17 : }
18 :
19 2 : bool ConverterToHTML::convert( const QString & path ) {
20 2 : if( !convert() ) {
21 0 : return false;
22 : }
23 :
24 2 : QFile file( path );
25 : file.open(
26 4 : QIODevice::OpenModeFlag::WriteOnly |
27 : QIODevice::OpenModeFlag::Text |
28 : QIODevice::OpenModeFlag::Truncate
29 2 : );
30 :
31 2 : if( !file.isOpen() ) {
32 0 : m_lastError = "The file can not be opened";
33 0 : return false;
34 : }
35 :
36 4 : QTextStream stream( &file );
37 2 : stream.setCodec( "UTF-8" );
38 2 : stream << m_html;
39 :
40 4 : return true;
41 : }
42 :
43 3 : bool ConverterToHTML::createHTML() {
44 3 : if(m_report.isNull())
45 : {
46 0 : m_lastError = "Report is empty";
47 0 : return false;
48 : }
49 :
50 3 : int pageHeight = m_report->getHeight();
51 3 : int pageWidth = m_report->getWidth();
52 3 : int freePageSpace = pageHeight;
53 :
54 6 : m_html += QString("<!DOCTYPE html>\n"
55 : "<html>\n"
56 : " <head>\n"
57 : " <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\n"
58 : " <title>Report</title>\n"
59 : " <style>\n"
60 :
61 : " div, .detail, .title, .band {\n"
62 : " position: relative;\n"
63 : " width: 100%;\n"
64 : " overflow: hidden;\n"
65 : " }\n"
66 :
67 : " @media print {\n"
68 : " .page {page-break-after: always;}\n"
69 : " }\n"
70 :
71 : " .page {\n"
72 : " width: %1px;\n"
73 : " height: %2px;\n"
74 : " }\n"
75 :
76 : " .statictext, .textfield, .shape{\n"
77 : " position: absolute;\n"
78 : " background-color: transparent;\n"
79 : " }\n"
80 :
81 : " .statictext {\n"
82 : " font-family: %3;\n"
83 : " font-size: %4pt;\n"
84 : " color: %5;\n"
85 : " font-style: %6;\n"
86 : " font-weight: %7;\n"
87 : " }\n"
88 :
89 : " .textfield {\n"
90 : " font-family: %8;\n"
91 : " font-size: %9pt;\n"
92 : " color: %10;\n"
93 : " font-style: %11;\n"
94 : " font-weight: %12;\n"
95 : " }\n"
96 :
97 : " </style>\n"
98 : " </head>\n"
99 : " <body>\n")
100 : .arg(pageWidth).arg(pageHeight)
101 : .arg("Verdana").arg("12").arg("black").arg("normal").arg("normal")
102 3 : .arg("Verdana").arg("12").arg("black").arg("normal").arg("normal");
103 :
104 3 : m_html += " <div class='page'>\n";
105 :
106 3 : auto title = m_report->getTitle();
107 :
108 3 : if(!title.isNull())
109 : {
110 2 : m_html += " <div class='title'>\n";
111 :
112 2 : detail::Replacer replacer;
113 2 : if( !replacer.replace( title, m_report, 0 ) )
114 : {
115 0 : m_lastError = "Error in replacing process: " + replacer.getLastError();
116 0 : return false;
117 : }
118 :
119 4 : for(auto && band : title->getBands())
120 : {
121 2 : QString elementStr = "";
122 :
123 4 : for(auto && textField : band->getTextFields())
124 : {
125 2 : if (textField->getText() != "")
126 : {
127 2 : QString textAlignment = "left";
128 4 : QString verticalAlignment = "middle";
129 :
130 2 : if ((textField->getAlignment() & Qt::AlignLeft) == Qt::AlignLeft)
131 2 : textAlignment = "left";
132 2 : if ((textField->getAlignment() & Qt::AlignRight) == Qt::AlignRight)
133 0 : textAlignment = "right";
134 2 : if ((textField->getAlignment() & Qt::AlignHCenter) == Qt::AlignHCenter)
135 0 : textAlignment = "center";
136 2 : if ((textField->getAlignment() & Qt::AlignJustify) == Qt::AlignJustify)
137 0 : textAlignment = "justify";
138 :
139 2 : if ((textField->getAlignment() & Qt::AlignTop) == Qt::AlignTop)
140 0 : verticalAlignment = "top";
141 2 : if ((textField->getAlignment() & Qt::AlignBottom) == Qt::AlignBottom)
142 2 : verticalAlignment = "bottom";
143 2 : if ((textField->getAlignment() & Qt::AlignVCenter) == Qt::AlignVCenter)
144 0 : verticalAlignment = "middle";
145 : //if ((textField->getAlignment() & Qt::AlignBaseline) == Qt::AlignBaseline)
146 : // verticalAlignment = "baseline";
147 :
148 14 : elementStr += QString(" <div class='textfield' "
149 : "style='left: %1px; top: %2px; "
150 : "width: %3px; height: %4px; "
151 : "text-align: %5; vertical-align: %6'>%7</div>\n")
152 2 : .arg(textField->getX())
153 2 : .arg(textField->getY())
154 2 : .arg(textField->getWidth())
155 2 : .arg(textField->getHeight())
156 : .arg(textAlignment)
157 : .arg(verticalAlignment)
158 6 : .arg(textField->getText());
159 : }
160 2 : }
161 :
162 4 : for(auto && staticText : band->getStaticTexts())
163 : {
164 2 : if (staticText->getText() != "")
165 : {
166 2 : QString textAlignment = "left";
167 4 : QString verticalAlignment = "middle";
168 :
169 2 : if ((staticText->getAlignment() & Qt::AlignLeft) == Qt::AlignLeft)
170 0 : textAlignment = "left";
171 2 : if ((staticText->getAlignment() & Qt::AlignRight) == Qt::AlignRight)
172 2 : textAlignment = "right";
173 2 : if ((staticText->getAlignment() & Qt::AlignHCenter) == Qt::AlignHCenter)
174 0 : textAlignment = "center";
175 2 : if ((staticText->getAlignment() & Qt::AlignJustify) == Qt::AlignJustify)
176 0 : textAlignment = "justify";
177 :
178 2 : if ((staticText->getAlignment() & Qt::AlignTop) == Qt::AlignTop)
179 2 : verticalAlignment = "top";
180 2 : if ((staticText->getAlignment() & Qt::AlignBottom) == Qt::AlignBottom)
181 0 : verticalAlignment = "bottom";
182 2 : if ((staticText->getAlignment() & Qt::AlignVCenter) == Qt::AlignVCenter)
183 0 : verticalAlignment = "middle";
184 : //if ((staticText->getAlignment() & Qt::AlignBaseline) == Qt::AlignBaseline)
185 : // verticalAlignment = "baseline";
186 :
187 :
188 14 : elementStr += QString(" <div class='statictext' "
189 : "style='left: %1px; top: %2px; "
190 : "width: %3px; height: %4px; "
191 : "text-align: %5; vertical-align: %6'>%7</div>\n")
192 2 : .arg(staticText->getX())
193 2 : .arg(staticText->getY())
194 2 : .arg(staticText->getWidth())
195 2 : .arg(staticText->getHeight())
196 : .arg(textAlignment)
197 : .arg(verticalAlignment)
198 6 : .arg(staticText->getText());
199 : }
200 2 : }
201 :
202 2 : drawShapes(band, elementStr, 0);
203 :
204 2 : freePageSpace -= band->getSize().height();
205 :
206 6 : m_html += QString(" <div class='band' "
207 : "style='height: %1px'>\n%2 </div>\n")
208 2 : .arg(band->getSize().height())
209 2 : .arg(elementStr);
210 4 : }
211 :
212 2 : m_html += " </div>\n";
213 : }
214 :
215 :
216 6 : auto detail = m_report->getDetail();
217 3 : if(detail.isNull())
218 : {
219 0 : m_lastError = "Report->Detail is empty";
220 0 : return false;
221 : }
222 :
223 3 : int pageCount = 0;
224 3 : int detailCount = m_report->getRowCount();
225 :
226 35 : for(int i = 0; i < detailCount; ++i)
227 : {
228 32 : detail::Replacer replacer;
229 32 : if( !replacer.replace( detail, m_report, i ) )
230 : {
231 0 : m_lastError = "Error in replacing process: " + replacer.getLastError();
232 0 : return false;
233 : }
234 :
235 64 : QString bandStr = "";
236 :
237 118 : for(auto && band : detail->getBands())
238 : {
239 86 : bool isBandEmpty = true;
240 86 : QString elementStr = "";
241 :
242 172 : for(auto && textField : band->getTextFields())
243 : {
244 86 : if (textField->getText() != "")
245 : {
246 86 : QString textAlignment = "left";
247 172 : QString verticalAlignment = "middle";
248 :
249 86 : if ((textField->getAlignment() & Qt::AlignLeft) == Qt::AlignLeft)
250 42 : textAlignment = "left";
251 86 : if ((textField->getAlignment() & Qt::AlignRight) == Qt::AlignRight)
252 44 : textAlignment = "right";
253 86 : if ((textField->getAlignment() & Qt::AlignHCenter) == Qt::AlignHCenter)
254 0 : textAlignment = "center";
255 86 : if ((textField->getAlignment() & Qt::AlignJustify) == Qt::AlignJustify)
256 0 : textAlignment = "justify";
257 :
258 86 : if ((textField->getAlignment() & Qt::AlignTop) == Qt::AlignTop)
259 44 : verticalAlignment = "top";
260 86 : if ((textField->getAlignment() & Qt::AlignBottom) == Qt::AlignBottom)
261 22 : verticalAlignment = "bottom";
262 86 : if ((textField->getAlignment() & Qt::AlignVCenter) == Qt::AlignVCenter)
263 20 : verticalAlignment = "middle";
264 : //if ((textField->getAlignment() & Qt::AlignBaseline) == Qt::AlignBaseline)
265 : // verticalAlignment = "baseline";
266 :
267 :
268 602 : elementStr += QString(" <div class='textfield' "
269 : "style='left: %1px; top: %2px; "
270 : "width: %3px; height: %4px; "
271 : "text-align: %5; vertical-align: %6'>%7</div>\n")
272 86 : .arg(textField->getX())
273 86 : .arg(textField->getY())
274 86 : .arg(textField->getWidth())
275 86 : .arg(textField->getHeight())
276 : .arg(textAlignment)
277 : .arg(verticalAlignment)
278 172 : .arg(textField->getText());
279 :
280 172 : isBandEmpty = false;
281 : }
282 86 : }
283 :
284 86 : if (!isBandEmpty)
285 : {
286 86 : for(auto && staticText : band->getStaticTexts())
287 : {
288 22 : if (staticText->getText() != "")
289 : {
290 22 : QString textAlignment = "left";
291 44 : QString verticalAlignment = "middle";
292 :
293 22 : if ((staticText->getAlignment() & Qt::AlignLeft) == Qt::AlignLeft)
294 0 : textAlignment = "left";
295 22 : if ((staticText->getAlignment() & Qt::AlignRight) == Qt::AlignRight)
296 22 : textAlignment = "right";
297 22 : if ((staticText->getAlignment() & Qt::AlignHCenter) == Qt::AlignHCenter)
298 0 : textAlignment = "center";
299 22 : if ((staticText->getAlignment() & Qt::AlignJustify) == Qt::AlignJustify)
300 0 : textAlignment = "justify";
301 :
302 22 : if ((staticText->getAlignment() & Qt::AlignTop) == Qt::AlignTop)
303 22 : verticalAlignment = "top";
304 22 : if ((staticText->getAlignment() & Qt::AlignBottom) == Qt::AlignBottom)
305 0 : verticalAlignment = "bottom";
306 22 : if ((staticText->getAlignment() & Qt::AlignVCenter) == Qt::AlignVCenter)
307 0 : verticalAlignment = "middle";
308 : //if ((staticText->getAlignment() & Qt::AlignBaseline) == Qt::AlignBaseline)
309 : // verticalAlignment = "baseline";
310 :
311 154 : elementStr += QString(" <div class='statictext' "
312 : "style='left: %1px; top: %2px; "
313 : "width: %3px; height: %4px; "
314 : "text-align: %5; vertical-align: %6'>%7</div>\n")
315 22 : .arg(staticText->getX())
316 22 : .arg(staticText->getY())
317 22 : .arg(staticText->getWidth())
318 22 : .arg(staticText->getHeight())
319 : .arg(textAlignment)
320 : .arg(verticalAlignment)
321 66 : .arg(staticText->getText());
322 : }
323 64 : }
324 :
325 64 : drawShapes(band, elementStr, i);
326 :
327 64 : if (freePageSpace < band->getSize().height())
328 : {
329 52 : m_html += QString(" <div class='detail'>\n%1 </div>\n")
330 26 : .arg(bandStr);
331 :
332 26 : ++pageCount;
333 : //колонтитул
334 26 : freePageSpace = pageHeight - band->getSize().height();
335 26 : m_html += " </div>\n <div class='page'>\n";
336 26 : bandStr = "";
337 : }
338 : else
339 38 : freePageSpace -= band->getSize().height();
340 :
341 192 : bandStr += QString(" <div class='band' "
342 : "style='height: %1px'>\n%2 </div>\n")
343 64 : .arg(band->getSize().height())
344 64 : .arg(elementStr);
345 : }
346 118 : }
347 :
348 64 : m_html += QString(" <div class='detail'>\n%1 </div>\n")
349 32 : .arg(bandStr);
350 32 : }
351 :
352 3 : ++pageCount;
353 : //Колонтитул
354 3 : m_html += " </div>\n </body>\n</html>\n";
355 6 : return true;
356 : }
357 :
358 66 : void ConverterToHTML::drawShapes(QSharedPointer<Band> band, QString &elementStr, int index)
359 : {
360 66 : int imgCount = 0;
361 :
362 90 : for (auto && image : band->getImages())
363 : {
364 24 : QImage img = image->getImage();
365 24 : img.save("img" + QString::number(index) + QString::number(imgCount) + ".jpg");
366 :
367 144 : elementStr += QString(" <div class='shape' "
368 : "style='left: %1px; top: %2px; "
369 : "width: %3px; height: %4px'>\n"
370 : " <img src='img%5%6.jpg' alt='img%5%6'>\n </div>\n")
371 24 : .arg(image->getX())
372 24 : .arg(image->getY())
373 24 : .arg(image->getWidth())
374 24 : .arg(image->getHeight())
375 : .arg(index)
376 24 : .arg(imgCount);
377 :
378 24 : ++imgCount;
379 90 : }
380 :
381 68 : for( auto && line : band->getLines() )
382 : {
383 2 : float angleRad = atan2(line->getHeight(), line->getWidth());
384 2 : float lineWidth = sqrt(pow(line->getWidth(), 2) + pow(line->getHeight(), 2));
385 :
386 12 : elementStr += QString(" <div class='shape' "
387 : "style='left: %1px; top: %2px; "
388 : "width: %3px; height: %4px; "
389 : "overflow: visible'>\n"
390 : " <div style='border-top: 1px solid black; height: 1px; width: %5px; "
391 : "transform-origin: 0 0 0; transform: rotate(%6rad)'></div>\n </div>\n")
392 2 : .arg(line->getX())
393 2 : .arg(line->getY())
394 2 : .arg(line->getWidth())
395 2 : .arg(line->getHeight())
396 : .arg(lineWidth)
397 2 : .arg(angleRad);
398 66 : }
399 :
400 68 : for( auto && rect : band->getRects() )
401 : {
402 12 : elementStr += QString(" <div class='shape' "
403 : "style='border: 1px solid black; left: %1px; top: %2px; "
404 : "width: %3px; height: %4px;'></div>\n")
405 2 : .arg(rect->getX())
406 2 : .arg(rect->getY())
407 2 : .arg(rect->getWidth())
408 4 : .arg(rect->getHeight());
409 66 : }
410 :
411 68 : for( auto && ellipse : band->getEllipses() )
412 : {
413 16 : elementStr += QString(" <div class='shape' "
414 : "style='border: 1px solid black; "
415 : "left: %1px; top: %2px; "
416 : "width: %3px; height: %4px; "
417 : "-moz-border-radius: %5px / %6px; "
418 : "-webkit-border-radius: %5px / %6px; "
419 : "border-radius: %5px / %6px;'></div>\n")
420 2 : .arg(ellipse->getX())
421 2 : .arg(ellipse->getY())
422 2 : .arg(ellipse->getWidth())
423 2 : .arg(ellipse->getHeight())
424 2 : .arg(ellipse->getWidth() / 2)
425 4 : .arg(ellipse->getHeight() / 2);
426 66 : }
427 66 : }
428 :
429 5 : const QString ConverterToHTML::getLastError() const {
430 5 : return m_lastError;
431 : }
432 :
433 3 : const QString ConverterToHTML::getHTML() const {
434 3 : return m_html;
435 : }
436 :
437 : }
438 : }
|