Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to convert QVariant to HTML



  • Hi!
    How to convert QVariant to HTML?


  • Lifetime Qt Champion

    Hi,

    What is in your QVariant ?



  • It's not exahustive but it's a start (source):

    QString saveVariant(const QVariant& val)
    {
        if (val.isNull())
            return QString();
        switch (val.type()) {
        case QMetaType::UnknownType:
            Q_ASSERT_X(false, "saveVariant", "Trying to save unregistered type.");
            return QString();
        case QMetaType::Bool: return val.toBool() ? QStringLiteral("1") : QStringLiteral("0");
        case QMetaType::Long:
        case QMetaType::Short:
        case QMetaType::Char:
        case QMetaType::SChar:
        case QMetaType::Int: return QString::number(val.toInt());
        case QMetaType::ULong:
        case QMetaType::UShort:
        case QMetaType::UChar:
        case QMetaType::UInt: return QString::number(val.toUInt());
        case QMetaType::LongLong: return QString::number(val.toLongLong());
        case QMetaType::ULongLong:  return QString::number(val.toULongLong());
        case QMetaType::Double:  
        case QMetaType::Float: return guessDecimalsString(val.toDouble());
        case QMetaType::QChar: return QString(val.toChar());
        case QMetaType::QString: return val.toString();
        case QMetaType::QByteArray: return QString::fromLatin1(val.toByteArray().toBase64());
        case QMetaType::QDate: return val.toDate().toString(Qt::ISODate);
        case QMetaType::QTime: return val.toTime().toString(Qt::ISODate);
        case QMetaType::QDateTime: return val.toDateTime().toString(Qt::ISODate);
        case QMetaType::QImage: return saveImageVariant(val.value<QImage>());
        case QMetaType::QPixmap: return saveImageVariant(val.value<QPixmap>().toImage());
        case QMetaType::QBitmap: return saveImageVariant(val.value<QBitmap>().toImage());
        default:
            return variantToString(val);
        }
    }
    QString saveImageVariant(const QImage& imageData)
    {
        QByteArray byteArray;
        QBuffer buffer(&byteArray);
        imageData.save(&buffer, "PNG");
        return QString::fromLatin1(byteArray.toBase64().constData());
    }
    QString variantToString(const QVariant& val)
    {
        QString result;
        QByteArray data;
        QDataStream outStream(&data, QIODevice::WriteOnly);
        outStream << val;
        data = qCompress(data);
        return QString::fromLatin1(data.toBase64());
    }
    void writeHtmlVariant(QXmlStreamWriter& writer, const QVariant& val)
    {
        if (isImageType(val.type())) {
            writer.writeEmptyElement(QStringLiteral("img"));
            writer.writeAttribute(QStringLiteral("src"), "data:image/png;base64," + saveVariant(val));
            writer.writeAttribute(QStringLiteral("alt"), QStringLiteral("modelimage.png"));
            return;
        }
        writer.writeCharacters(saveVariant(val));
    }
    bool isImageType(int val) {
        switch(val){
        case QMetaType::QImage:
        case QMetaType::QPixmap:
        case QMetaType::QBitmap:
            return true;
        }
        return false;
    }
    


  • @SGaist In QVariant text and images from .docx file.



  • @VRonin it doesn't compile


  • Qt Champions 2019

    @Mikeeeeee said in How to convert QVariant to HTML:

    it doesn't compile

    Then fix the issues in the code or at least post the compiler errors...



  • Too many errors, not enough files



  • @Mikeeeeee said in How to convert QVariant to HTML:

    Too many errors

    Fixed and turned into a working minimal example:

    #include <QGuiApplication>
    #include <QDataStream>
    #include <QMetaType>
    #include <QXmlStreamWriter>
    #include <QBuffer>
    #include <QImage>
    #include <QBitmap>
    #include <QPixmap>
    #include <QVariant>
    #include <QDateTime>
    #include <QFile>
    
    int guessDecimals(double val)
    {
        int precision = 0;
        for (double junk = 0; !qFuzzyIsNull(std::modf(val, &junk)); ++precision)
            val *= 10.0;
        return precision;
    }
    QString guessDecimalsString(double val, QLocale* loca  = Q_NULLPTR)
    {
        if (loca)
            return loca->toString(val, 'f', guessDecimals(val));
        return QString::number(val, 'f', guessDecimals(val));
    }
    bool isImageType(int val) {
        switch(val){
        case QMetaType::QImage:
        case QMetaType::QPixmap:
        case QMetaType::QBitmap:
            return true;
        }
        return false;
    }
    QString saveImageVariant(const QImage& imageData)
    {
        QByteArray byteArray;
        QBuffer buffer(&byteArray);
        imageData.save(&buffer, "PNG");
        return QString::fromLatin1(byteArray.toBase64().constData());
    }
    QString variantToString(const QVariant& val)
    {
        QString result;
        QByteArray data;
        QDataStream outStream(&data, QIODevice::WriteOnly);
        outStream << val;
        data = qCompress(data);
        return QString::fromLatin1(data.toBase64());
    }
    
    QString saveVariant(const QVariant& val)
    {
        if (val.isNull())
            return QString();
        switch (val.type()) {
        case QMetaType::UnknownType:
            Q_ASSERT_X(false, "saveVariant", "Trying to save unregistered type.");
            return QString();
        case QMetaType::Bool: return val.toBool() ? QStringLiteral("1") : QStringLiteral("0");
        case QMetaType::Long:
        case QMetaType::Short:
        case QMetaType::Char:
        case QMetaType::SChar:
        case QMetaType::Int: return QString::number(val.toInt());
        case QMetaType::ULong:
        case QMetaType::UShort:
        case QMetaType::UChar:
        case QMetaType::UInt: return QString::number(val.toUInt());
        case QMetaType::LongLong: return QString::number(val.toLongLong());
        case QMetaType::ULongLong:  return QString::number(val.toULongLong());
        case QMetaType::Double:
        case QMetaType::Float: return guessDecimalsString(val.toDouble());
        case QMetaType::QChar: return QString(val.toChar());
        case QMetaType::QString: return val.toString();
        case QMetaType::QByteArray: return QString::fromLatin1(val.toByteArray().toBase64());
        case QMetaType::QDate: return val.toDate().toString(Qt::ISODate);
        case QMetaType::QTime: return val.toTime().toString(Qt::ISODate);
        case QMetaType::QDateTime: return val.toDateTime().toString(Qt::ISODate);
        case QMetaType::QImage: return saveImageVariant(val.value<QImage>());
        case QMetaType::QPixmap: return saveImageVariant(val.value<QPixmap>().toImage());
        case QMetaType::QBitmap: return saveImageVariant(val.value<QBitmap>().toImage());
        default:
            return variantToString(val);
        }
    }
    void writeHtmlVariant(QXmlStreamWriter& writer, const QVariant& val)
    {
        if (isImageType(val.type())) {
            writer.writeEmptyElement(QStringLiteral("img"));
            writer.writeAttribute(QStringLiteral("src"), "data:image/png;base64," + saveVariant(val));
            writer.writeAttribute(QStringLiteral("alt"), QStringLiteral("modelimage.png"));
            return;
        }
        writer.writeCharacters(saveVariant(val));
    }
    
    
    int main(int argc, char **argv) {
        QGuiApplication app(argc,argv);
        QFile htmlOutPut("TestOutput.html");
        if(!htmlOutPut.open(QIODevice::WriteOnly))
            return 1;
        htmlOutPut.write(QByteArrayLiteral("<!DOCTYPE html>"));
        QXmlStreamWriter htmlWriter(&htmlOutPut);
        htmlWriter.writeStartElement(QStringLiteral("html"));
        htmlWriter.writeAttribute(QStringLiteral("xmlns"),QStringLiteral("http://www.w3.org/1999/xhtml"));
        htmlWriter.writeAttribute(QStringLiteral("lang"),QStringLiteral("en"));
        htmlWriter.writeAttribute(QStringLiteral("xml:lang"),QStringLiteral("en"));
        htmlWriter.writeStartElement(QStringLiteral("head"));
        htmlWriter.writeEmptyElement(QStringLiteral("meta"));
        htmlWriter.writeAttribute(QStringLiteral("http-equiv"),QStringLiteral("Content-Type"));
        htmlWriter.writeAttribute(QStringLiteral("content"),QStringLiteral("text/html; charset=utf-8"));
        htmlWriter.writeStartElement(QStringLiteral("title"));
        htmlWriter.writeCharacters(QStringLiteral("Testing Variant to Html"));
        htmlWriter.writeEndElement(); //title
        htmlWriter.writeEndElement(); //head
        htmlWriter.writeStartElement(QStringLiteral("body"));
        htmlWriter.writeStartElement(QStringLiteral("p"));
        writeHtmlVariant(htmlWriter, QStringLiteral("The magic number is: "));
        writeHtmlVariant(htmlWriter, 88);
        writeHtmlVariant(htmlWriter, QStringLiteral(" and "));
        writeHtmlVariant(htmlWriter, 3.21);
        htmlWriter.writeEndElement(); //p
        QPixmap blueImage(200,200);
        blueImage.fill(Qt::blue);
        writeHtmlVariant(htmlWriter,blueImage);
        htmlWriter.writeEndDocument();
        return 0;
    }
    

    In QVariant text and images from .docx file.

    What does this mean?



  • Excuse me.
    This is compiled.
    But if I do this:

    HTMLString = ConvertDocInHTML::saveVariant(HTMLQVariant);
    

    ing an error:
    D:\QTProject\ReaderResume\mainwindow.cpp:1198: ошибка: cannot call member function 'QString ConvertDocInHTML::saveVariant(const QVariant&)' without object
    HTMLResume = ConvertDocInHTML::saveVariant(HTMLQVariant);
    ^



  • put a static in front of the method declaration



  • this method returns plain text, not HTML


  • Lifetime Qt Champion

    @Mikeeeeee
    hi
    But html is plain text.
    like

    <html><head/><body><p><span style=" font-size:8.25pt; font-weight:600;">THIS IS HTML</span></p></body></html>
    

    I think you need to explain better what you have in the QVariant and what you wish to convert it to.



  • Sarcastic response:

    QString getHTML(){
      return QString("HTML");
    }
    

    Seriously, what html do you need? The full document, an excerpt? Conversion of one document to another? A really naive approach could be:

    QString getHTML(QVariant data){
      return QString("<div>"+data.toString()+"</div>");
    }
    

    This returns a valid HTML string that is wrapped by an HTML tag. Not a full document, but usable in a larger document producing construct.



  • I have .docx file.
    I get simple text from .docx:

    QString ResumeFileName ("");
        ResumeFileName = QFileDialog::getOpenFileName(0, "Text ", "", "*.doc *.docx *.rtf");
        ResumeFileName.replace(QRegExp("[/]"), "\\");
        qDebug()<<ResumeFileName;
        if (ResumeFileName != "")
        {
            QAxObject   wordApplication("Word.Application");
            QAxObject *documents = wordApplication.querySubObject("Documents");
            QAxObject *document = documents->querySubObject("Open(const QString&, bool)", ResumeFileName, true);
            QAxObject *words = document->querySubObject("Words");
            QString TextResume;
            QString HTMLResume;
            int countWord = words->dynamicCall("Count()").toInt();
            for (int a = 1; a <= countWord; a++){
                TextResume.append(words->querySubObject("Item(int)", a)->dynamicCall("Text()").toString());
                HTMLResume.append(words->querySubObject("Item(int)", a)->dynamicCall("Text()").SomethingFfunction);
            }
            document->dynamicCall("Close (boolean)", false);
            TextResume.replace(QRegExp("[\r]"), "\r\n"); 
            qDebug()<<TextResume;
    

    But I also need text with formatting and pictures


Log in to reply