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 4 : QFile file( path ); 25 2 : 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 2 : 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 3 : 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 6 : .arg(pageWidth).arg(pageHeight) 101 12 : .arg("Verdana").arg("12").arg("black").arg("normal").arg("normal") 102 12 : .arg("Verdana").arg("12").arg("black").arg("normal").arg("normal"); 103 : 104 3 : m_html += " <div class='page'>\n"; 105 : 106 6 : auto title = m_report->getTitle(); 107 : 108 3 : if(!title.isNull()) 109 : { 110 2 : m_html += " <div class='title'>\n"; 111 : 112 4 : 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 4 : QString elementStr = ""; 122 : 123 4 : for(auto && textField : band->getTextFields()) 124 : { 125 2 : if (textField->getText() != "") 126 : { 127 4 : 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 : 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 4 : .arg(textField->getX()) 153 8 : .arg(textField->getY()) 154 8 : .arg(textField->getWidth()) 155 8 : .arg(textField->getHeight()) 156 8 : .arg(textAlignment) 157 8 : .arg(verticalAlignment) 158 6 : .arg(textField->getText()); 159 : } 160 : } 161 : 162 4 : for(auto && staticText : band->getStaticTexts()) 163 : { 164 2 : if (staticText->getText() != "") 165 : { 166 4 : 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 : 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 4 : .arg(staticText->getX()) 193 8 : .arg(staticText->getY()) 194 8 : .arg(staticText->getWidth()) 195 8 : .arg(staticText->getHeight()) 196 8 : .arg(textAlignment) 197 8 : .arg(verticalAlignment) 198 6 : .arg(staticText->getText()); 199 : } 200 : } 201 : 202 2 : drawShapes(band, elementStr, 0); 203 : 204 2 : freePageSpace -= band->getSize().height(); 205 : 206 2 : m_html += QString(" <div class='band' " 207 : "style='height: %1px'>\n%2 </div>\n") 208 4 : .arg(band->getSize().height()) 209 8 : .arg(elementStr); 210 : } 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 64 : 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 172 : QString elementStr = ""; 241 : 242 172 : for(auto && textField : band->getTextFields()) 243 : { 244 86 : if (textField->getText() != "") 245 : { 246 172 : 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 : 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 172 : .arg(textField->getX()) 273 344 : .arg(textField->getY()) 274 344 : .arg(textField->getWidth()) 275 344 : .arg(textField->getHeight()) 276 344 : .arg(textAlignment) 277 344 : .arg(verticalAlignment) 278 258 : .arg(textField->getText()); 279 : 280 86 : isBandEmpty = false; 281 : } 282 : } 283 : 284 86 : if (!isBandEmpty) 285 : { 286 86 : for(auto && staticText : band->getStaticTexts()) 287 : { 288 22 : if (staticText->getText() != "") 289 : { 290 44 : 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 : 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 44 : .arg(staticText->getX()) 316 88 : .arg(staticText->getY()) 317 88 : .arg(staticText->getWidth()) 318 88 : .arg(staticText->getHeight()) 319 88 : .arg(textAlignment) 320 88 : .arg(verticalAlignment) 321 66 : .arg(staticText->getText()); 322 : } 323 : } 324 : 325 64 : drawShapes(band, elementStr, i); 326 : 327 64 : if (freePageSpace < band->getSize().height()) 328 : { 329 26 : m_html += QString(" <div class='detail'>\n%1 </div>\n") 330 52 : .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 : bandStr += QString(" <div class='band' " 342 : "style='height: %1px'>\n%2 </div>\n") 343 128 : .arg(band->getSize().height()) 344 192 : .arg(elementStr); 345 : } 346 : } 347 : 348 32 : m_html += QString(" <div class='detail'>\n%1 </div>\n") 349 64 : .arg(bandStr); 350 : } 351 : 352 3 : ++pageCount; 353 : //Колонтитул 354 3 : m_html += " </div>\n </body>\n</html>\n"; 355 3 : 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 48 : QImage img = image->getImage(); 365 24 : img.save("img" + QString::number(index) + QString::number(imgCount) + ".jpg"); 366 : 367 : 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 48 : .arg(image->getX()) 372 96 : .arg(image->getY()) 373 96 : .arg(image->getWidth()) 374 96 : .arg(image->getHeight()) 375 96 : .arg(index) 376 72 : .arg(imgCount); 377 : 378 24 : ++imgCount; 379 : } 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 : 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 4 : .arg(line->getX()) 393 8 : .arg(line->getY()) 394 8 : .arg(line->getWidth()) 395 8 : .arg(line->getHeight()) 396 8 : .arg(lineWidth) 397 6 : .arg(angleRad); 398 : } 399 : 400 68 : for( auto && rect : band->getRects() ) 401 : { 402 : elementStr += QString(" <div class='shape' " 403 : "style='border: 1px solid black; left: %1px; top: %2px; " 404 : "width: %3px; height: %4px;'></div>\n") 405 4 : .arg(rect->getX()) 406 8 : .arg(rect->getY()) 407 8 : .arg(rect->getWidth()) 408 6 : .arg(rect->getHeight()); 409 : } 410 : 411 68 : for( auto && ellipse : band->getEllipses() ) 412 : { 413 : 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 4 : .arg(ellipse->getX()) 421 8 : .arg(ellipse->getY()) 422 8 : .arg(ellipse->getWidth()) 423 8 : .arg(ellipse->getHeight()) 424 8 : .arg(ellipse->getWidth() / 2) 425 6 : .arg(ellipse->getHeight() / 2); 426 : } 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 : }