Russian Qt Forum
Ноябрь 25, 2024, 12:00 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: QT База данных отчет (reports)  (Прочитано 19312 раз)
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #15 : Январь 19, 2017, 23:58 »

Все программеры на дельфях такие неадекватные?
Записан
GraninDm
Гость
« Ответ #16 : Январь 20, 2017, 08:38 »

panAlexey Это было круто сказано молодец,у вас наверное тоже есть проблемы. Проблема мне кажется исключительно в вас. У вас просто не хватает времени.

Проблема в вас. panAlexey пытался. А вы только ноете.
Нужен вам отчет непосредтвенно в IDE напишите плагин и пользуйтесь.
Я же вас спросил что не получается с LimeReport. Вы молчите.
Значит конструктивно беседу вы вести не хотите.

Я раньше на Visual FoxPro писал.
И после него писать учетные системы на Qt не очень удобно.
Мне в Qt не хватало после VFP
1. Редактируемых курсоров типа QEditSqlQury (написал свою, конечно по функциональности не как в VFP, но мне хватает)
2. Отчетов. (LimeReport использую. никаких проблем)
3. В Qt нет numeric типов. Вот это меня действительно напрягает, но пока обхожусь QDouble. Написал свою замену, но чтобы внедрить ее Qt нужно дофига всего переделывать
И драйвер psql и модели и контролы.

Я даже драйвер pqsql одно время под себя допиливал. Сейчас это все есть уже в Qt.
Так что или начинайте писать и задавать конкретные вопросы или идите на форум Дельфи и там нойте о плохой Qt.

И еще можете этот топик своему начальнику показать - пусть посмеется.
Записан
Hornet
Гость
« Ответ #17 : Январь 20, 2017, 10:51 »

GraninDm вы читать умеете "Вопрос знатокам LimeReport  можно связать с компилированным проектом qt или это отдельная фича"
что имеется в виду. Созданные отчеты в LimeReport привязать в форме проекта. Объясняю при нажатии кнопки в форме открывался отчет
созданный в LimeReport, и вы водил данные на монитор без установленной среды LimeReport.
А начальнику уже показал долго ржал над заумными адекватными qt программистами которые четко дают ответы на поставленные им воросы как то так:
 у меня так...
INCLUDEPATH += \
    $$PWD/../../LimeReport/include \
    и т.д.

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../LimeReport/build/5.6.0/win32/release/lib -llimereport
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../LimeReport/build/5.6.0/win32/debug/lib -llimereport
else:unix:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../lib/debug -llimereport
else:unix:CONFIG(release, debug|release): LIBS += -L$$PWD/../../lib/release -llimereport

Четкий адекватный ответ программера qt. Молодец возьми  с полки порожок.
Записан
GraninDm
Гость
« Ответ #18 : Январь 20, 2017, 10:57 »

Вопросы сначала научитесь задавать.
Мне насрать на ваш скомпилированный проект.
Вам шашечки или ехать?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #19 : Январь 20, 2017, 12:11 »

Цитировать
Тайг
пост у них. на неделю.

Naid Hatred
понятно....

Тайг
мясо женщин и алкоголь исключить

Naid Hatred
запятые проставь, плз

Naid Hatred
а то ты меня пугаешь

Ну вы поняли.
Записан
GraninDm
Гость
« Ответ #20 : Январь 20, 2017, 12:23 »

GraninDm вы читать умеете "Вопрос знатокам LimeReport  можно связать с компилированным проектом qt или это отдельная фича"
что имеется в виду. Созданные отчеты в LimeReport привязать в форме проекта. Объясняю при нажатии кнопки в форме открывался отчет
созданный в LimeReport, и вы водил данные на монитор без установленной среды LimeReport.
Я все таки отвечу...
Да. Можно.
И чё дальше?

И при чем тут среда LimeReport. Что это вообще такое среда??
Что трудно dll к проекту подцепить?
« Последнее редактирование: Январь 20, 2017, 12:24 от GraninDm » Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #21 : Февраль 01, 2017, 02:10 »

Может создать форму, внутри отображение html теги, для вывода данных.
как вы решаете проблему.
Самый распространенный вариант решения - html. QTextDocument + QTextEdit.
Или QWebView.
Можно напрямую формировать отчет работая с Excel, Word, OO, LO.
Вариантов дохрена.
Согласен, самый простой вариант сделать генератор отчетов на базе HTML c шаблонами. На мой взгляд все эти убогие генераторы отчетов с собственными редакторами - идиотизм. Можно сделать и простой редактор для отчетов - буквально пару кнопок добавить в кт-пример, для реализации вставки таблиц и объединения ячеек.

Ниже простой пример генератора отчетов, рабочий. Читается шаблон, есть методы для замены в шаблоне текстовых переменных, заполнения таблиц из контейнера или из другой модели. Функционал можно наращивать под потребности бесконечно и главное легко. Шаблон отчета всегда можно просмотреть глазами и сторонними редакторами т.к. это HTML. Его может быстро подправить любой человек (не программист) - например исправить грамматические ошибки или сделать аналог на другом языке. Средствами Qt сразу работает как документ ODF или HTML.

Код:
#pragma once

#include <QString>
#include <QTextDocument>
#include <QTextCursor>
#include <QAbstractItemModel>

class CReportMaker
{
private:
QString m_sOfficePath;
QString m_sBrowserPath;
QString m_sReportPath;
// Instance
static CReportMaker * s_pInstance;

public:
enum exportFileType {
eftHTML,
eftODT,
eftCount
};
typedef QHash<QString, QVariant> TableRowDesc;

QString eftToString( exportFileType eftVal );
QString appByEFT( exportFileType eftVal );

// Instance
inline static CReportMaker * instance() { return s_pInstance; }

CReportMaker();
~CReportMaker();

bool loadReportTemplate( QTextDocument& textDoc, const QString& sFName );

void doSimpleReplacement( QTextDocument& textDoc, QHash<QString, QVariant>& simpleReplacement );
void doTableReplacement(QTextDocument& textDoc, const QString &sTableName, QVector<TableRowDesc> tableReplacement );
void doTableReplacement(QTextDocument& textDoc, const QString &sTableName, const QAbstractItemModel& model );

void saveAndOpen( const QTextDocument& textDoc, exportFileType eftVal, const QString& sFName );
};

// Shortcuts
inline CReportMaker * reportMaker() { return CReportMaker::instance(); }

Код:
#include "ReportMaker.h"

#include "FileUtils.h"
#include "SettingsManager.h"
#include <QTextDocumentWriter>
#include <QProcess>
#include <QTextCodec>
#include <QTextTable>
#include <QDebug>
#include <StringUtils.h>

CReportMaker * CReportMaker::s_pInstance = 0;

QString CReportMaker::eftToString(CReportMaker::exportFileType eftVal)
{
static const QString eftStrings[ eftCount ] =
{
"html",
"odt"
};
return eftStrings[ eftVal ];
}

QString CReportMaker::appByEFT(CReportMaker::exportFileType eftVal)
{
switch ( eftVal )
{
case eftHTML: return m_sBrowserPath;
case eftODT: return m_sOfficePath;
default: return "";
}
}

CReportMaker::CReportMaker()
{
Q_ASSERT( !s_pInstance );

// Save instance pointer
s_pInstance = this;

// **********************************************
CXmlSettings * pXml = settingsManager()->xml();
pXml->beginGroup("report_settings");
m_sOfficePath  = pXml->value( "OfficeProgram",  "libreoffice" ).toString();
m_sBrowserPath = pXml->value( "BrowserProgram", "firefox" ).toString();
m_sReportPath  = pXml->value( "ReportPath",     dataPath() + "Reports/" ).toString();
pXml->endGroup();
}

CReportMaker::~CReportMaker()
{
Q_ASSERT( s_pInstance );
s_pInstance = 0;
}

bool CReportMaker::loadReportTemplate( QTextDocument &textDoc, const QString &sFName)
{
if ( !QFile::exists( sFName ) )
{
qCritical() << "File not found:" << sFName;
return false;
}

QFile file( sFName );
if ( !file.open(QFile::ReadOnly) )
{
qCritical() << "Failed to report open file:" << sFName;
return false;
}

QByteArray data = file.readAll();

QTextCodec *codec = Qt::codecForHtml(data);
QString str = codec->toUnicode(data);

if ( !Qt::mightBeRichText(str) )
{
qCritical() << "Failed to parse HTML report file:" << sFName;
return false;
}

textDoc.setHtml( str );

return true;
}

void CReportMaker::doSimpleReplacement( QTextDocument &textDoc, QHash<QString, QVariant>& simpleReplacement)
{
QHashIterator<QString, QVariant> i(simpleReplacement);
while ( i.hasNext() )
{
i.next();
QString sLetter = i.key();
QVariant val = i.value();

QTextCursor cur = textDoc.find( sLetter );
while ( !cur.isNull() )
{
QTextCharFormat cfmt = cur.charFormat();
cur.deleteChar();
cur.setBlockCharFormat( cfmt );
cur.insertText( val.toString() );
cur = textDoc.find( sLetter, cur );
}
}
}

void CReportMaker::doTableReplacement( QTextDocument &textDoc, const QString& sTableName, QVector<CReportMaker::TableRowDesc> tableReplacement)
{
QTextCursor cur = textDoc.find( sTableName );
if ( !cur.isNull() )
{
QTextCharFormat cfmt = cur.charFormat();
cur.deleteChar();
cur.setBlockCharFormat( cfmt );
while ( !cur.currentTable() )
cur.movePosition( QTextCursor::Right );

QTextTable * pTable = cur.currentTable();

// заполняем ассоциацию имен колонок к их номерам, в последней строке таблицы должны в ячейках быть только имена выводимых колонок
QHash<int, QString> fieldByColumn;
QHash<int, QTextCharFormat> cfmtByColumn;
int nLastRow = pTable->rows()-1;
for ( int nCol = 0; nCol < pTable->columns(); ++nCol )
{
QTextCursor curStartCell = pTable->cellAt( nLastRow, nCol ).firstCursorPosition();
curStartCell.select( QTextCursor::WordUnderCursor );
fieldByColumn.insert( nCol, curStartCell.selectedText() );
cfmtByColumn.insert( nCol, curStartCell.charFormat() );
}

pTable->removeRows( nLastRow, 1 );

for ( int i = 0; i < tableReplacement.count(); ++i )
{
pTable->appendRows( 1 );

TableRowDesc row = tableReplacement.at( i );

int nLastRow = pTable->rows()-1;
for ( int nCol = 0; nCol < pTable->columns(); ++nCol )
{
QTextCursor cur = pTable->cellAt( nLastRow, nCol ).firstCursorPosition();

// Для этого поля не был запомнен номер колонки ( не была указана колонка с таким именем в первой строке таблицы шаблона )
if ( !fieldByColumn.contains( nCol ) ) continue;

QString sText = row.value( fieldByColumn.value( nCol ) ).toString();
cur.setBlockCharFormat( cfmtByColumn.value( nCol ) );
cur.insertText( sText );
}
}
}
}

void CReportMaker::doTableReplacement(QTextDocument &textDoc, const QString &sTableName, const QAbstractItemModel &model)
{
QTextCharFormat defaultFormat;
defaultFormat.setFontPointSize(12);

QTextCharFormat headerFormat;
headerFormat.setFontPointSize(12);
headerFormat.setFontWeight(QFont::Bold);

QTextTableFormat tableFormat;
tableFormat.setCellPadding(2.0);
tableFormat.setHeaderRowCount(1);
tableFormat.setBorderStyle( QTextFrameFormat::BorderStyle_Solid );
tableFormat.setBorderBrush( Qt::black );
tableFormat.setWidth( 10 );

QVector<QTextLength>  constraints;
constraints << QTextLength() << QTextLength() << QTextLength();
tableFormat .setColumnWidthConstraints(constraints);
tableFormat .setWidth(QTextLength(QTextLength::PercentageLength, 100));

QTextCursor cur = textDoc.find( sTableName );
if ( !cur.isNull() )
{
QTextCharFormat cfmt = cur.charFormat();
cur.deleteChar();
cur.setBlockCharFormat( cfmt );

cur.insertTable(1, model.columnCount(), tableFormat);

// заголовок таблицы
for ( int i=0; i < model.columnCount(); ++i )
{
cur.insertText( model.headerData(i, Qt::Horizontal).toString(), headerFormat );
cur.movePosition(QTextCursor::NextCell);
}

// таблица
for (int row = 0; row < model.rowCount(); ++row)
{
cur.currentTable()->appendRows(1);
cur.movePosition( QTextCursor::PreviousRow );
cur.movePosition( QTextCursor::NextCell );

for ( int col=0; col < model.columnCount(); ++col )
{

QVariant vVal = model.data( model.index(row, col) );

QString sVal = VariantToStringIFDT( vVal );

cur.insertText( sVal, defaultFormat );
cur.movePosition( QTextCursor::NextCell );
}
}
}
}

void CReportMaker::saveAndOpen(const QTextDocument &textDoc, CReportMaker::exportFileType eftVal, const QString &sFName)
{
// создаем папку для отчетов если ее не было
QDir dir( m_sReportPath );
if ( !dir.exists() )
dir.mkpath( m_sReportPath );

QString fileName =  m_sReportPath + sFName + "." + eftToString( eftVal );

QTextDocumentWriter writer(fileName);
//writer.setFormat("HTML"); // по непонятной причине вызов не требуется
writer.write(&textDoc);

QStringList args;
args << fileName;

QProcess * app = new QProcess;
app->start( appByEFT( eftVal ), args);
}
Записан
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #22 : Февраль 01, 2017, 09:43 »

Согласен, самый простой вариант сделать генератор отчетов на базе HTML c шаблонами. На мой взгляд все эти убогие генераторы отчетов с собственными редакторами - идиотизм.
Они решают определенные задачи: ускорение и удобство макетинга, подгонка печати и т.п.
Я просто с юзерами напрямую работаю и их нужды боль-мень знаю.
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #23 : Февраль 01, 2017, 16:15 »

Да мы вроде все тут с юзерами работаем.
Вот в том и дело, что юзеру проще открыть документ в редакторе похожем на ворд и там поправить что-то, чем осваивать неудобные редакторы шаблонов для отчетов с их бендами и скрытой логикой, которую может понять только программист.

Я очень много в Делфи работал с ФастРепорт, вижу что и сейчас тенденция использования таких систем генерации отчетов сохранена. Когда уже в конец надоело работать с этим г.., перешел на простой компонент, который делал отчеты на базе шаблонов из РТФ - и просто в шоке был от такого насколько жизнь может быть проще.

Я даже для Qt сначала сделал генерацию из RTF шаблона, но там когда дело касается таблиц возникают необнозначности при парсинге самого RTF, формат построен таким образом, что предполагалось его парсить прямо на лету переводя команды из документа в команды курсора. И HTML в связке с QTextDocument оказался очень быстрым и удобным решением, который можно перевести в любые форматы.
Записан
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #24 : Февраль 01, 2017, 16:48 »

Да мы вроде все тут с юзерами работаем.
Везде есть специфика. Табличные отчеты повторяют ексил, а с ексилом помоему только неандерталец не работал.
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
TEHb
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #25 : Февраль 02, 2017, 13:12 »

На мой взгляд все эти убогие генераторы отчетов с собственными редакторами - идиотизм.
Идиотизм - считать, что обладаешь абсолютным знанием и знаешь единственно верное решение.
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #26 : Февраль 02, 2017, 18:29 »

На мой взгляд все эти убогие генераторы отчетов с собственными редакторами - идиотизм.
Идиотизм - считать, что обладаешь абсолютным знанием и знаешь единственно верное решение.
Ты если читаешь - читай внимательно, тролль, набивающий карму счетчиком сообщений. - Если написано "На мой взгляд" - это уже никак не претендует на абсолютное знание. Да и вообще пошел отсюда толстый. )))
Записан
TEHb
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #27 : Февраль 02, 2017, 19:15 »

Я это написал это не для кармы Улыбающийся Просто ваша формулировка IMHO была несколько некорректной. 
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #28 : Февраль 02, 2017, 19:22 »

Цитировать
Я это написал это не для кармы Улыбающийся Просто ваша формулировка IMHO была несколько некорректной.
+1 сообщение к твоей карме ))))) +1 несодержательное и захламляющее тему - давай тролль жги!!!!!!
А модератор пусть удалит это все)
P.S.: Моя формлуировка  IMHO - ну не может быть некорректной, т.к. это мое видение ситуации.
Записан
TEHb
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #29 : Февраль 02, 2017, 19:30 »

Правильно ли я понимаю, что по вашему мнению все кто пользуются генераторами отчетов идиоты ?
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.059 секунд. Запросов: 23.