ОБНОВИТЬ
Я также сделал пост об этой проблеме на форумах WT здесь http://redmine.webtoolkit.eu/issues/3042. Для тех из вас, кто ищет дополнительную информацию по стайлингу, вы найдете там больше информации.
ОРИГИНАЛЬНАЯ ПОЧТА
У меня проблема с размещением WGroupBox (в конечном итоге WTable) в PDF. Я использую пример кода PDF из галереи виджетов и пытаюсь поместить его в таблицу WTable, которая у меня есть, но в случае неудачи я вернул его обратно в WGroupBox.
http://www.webtoolkit.eu/widgets/media/pdf-output
Образцы «PDF Images» работают нормально.
«Рендеринг HTML в PDF» — вот где у меня проблемы.
Я использую пример в точности так, как он отображается на странице, единственное добавление — указатель WContainerWidget для элементов, которые мне нужны в PDF.
Я не понимаю, что мне нужно передать в функцию renderPdf как WString, которая будет передана в функцию рендеринга WPdfRenderer. Я попытался изучить html кода галереи виджетов, чтобы сравнить с моим собственным, и подражать тому, что делает галерея , но все до сих пор не удалось сделать PDF.
Вот как выглядит URL после того, как я нажимаю кнопку «Создать PDF», он отображает пустую страницу с пустым pdf-сообщением «Загрузка» внизу слева.
http://127.0.0.1:8080/ui/report.pdf?wtd=Psx1WfLVpsvVDpxW&request=resource&resource=oylm6i6&rand=1
Пример кода ниже.
//This is the code I have executing on my main page, just a group box with a few labels, a button for the sample pdf, a chart, and another button for the more advanced sample pdf(this one is broken).
//PDF Images sample/////////////////////////////////////////////////////////////////////////
Wt::WContainerWidget* container = table_container;
Wt::WResource* sample_pdf = new SamplePdfResource(container);
Wt::WPushButton* button1 = new Wt::WPushButton("Create pdf sample", container);
button1->setLink(sample_pdf);
//PDF Images sample chart///////////////////////////////////////////////////////////////////
Wt::Chart::WCartesianChart* chart = CreateCartesianChart(table_container);
Wt::WPainter* p = new Wt::WPainter((Wt::WPdfImage*)sample_pdf);
chart->paint(*p);
std::ofstream f("chart.pdf", std::ios::out | std::ios::binary);
sample_pdf->write(f);
//GroupBox to be placed into PDF////////////////////////////////////////////////////////////
Wt::WGroupBox* group_box = new Wt::WGroupBox("Example Group Box", table_container);
group_box->addStyleClass("example");
Wt::WText* text = new Wt::WText("This is a text sample within the group box 1", group_box);
text = new Wt::WText("This is a text sample within the group box 2", group_box);
text = new Wt::WText("This is a text sample within the group box 3", group_box);
//The pdf to take the GroupBox//////////////////////////////////////////////////////////////
Wt::WPushButton* button = new Wt::WPushButton("Create pdf", container);
Wt::WResource* pdf = new ReportResource(group_box, container);
button->setLink(pdf);
Ниже приведен код «Отображение HTML в PDF» из галереи виджетов с новым контейнерным виджетом для цели.
namespace {
void HPDF_STDCALL error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *user_data) {
fprintf(stderr, "libharu error: error_no=%04X, detail_no=%d\n",
(unsigned int) error_no, (int) detail_no);
}
}
class ReportResource : public Wt::WResource
{
public:
ReportResource(Wt::WContainerWidget* target, Wt::WObject* parent = 0)
: Wt::WResource(parent),
_target(NULL)
{
suggestFileName("report.pdf");
_target = target;
}
virtual void handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response)
{
response.setMimeType("application/pdf");
HPDF_Doc pdf = HPDF_New(error_handler, 0);
// Note: UTF-8 encoding (for TrueType fonts) is only available since libharu 2.3.0 !
HPDF_UseUTFEncodings(pdf);
renderReport(pdf);
HPDF_SaveToStream(pdf);
unsigned int size = HPDF_GetStreamSize(pdf);
HPDF_BYTE *buf = new HPDF_BYTE[size];
HPDF_ReadFromStream (pdf, buf, &size);
HPDF_Free(pdf);
response.out().write((char*)buf, size);
delete[] buf;
}
private:
Wt::WContainerWidget* _target;
void renderReport(HPDF_Doc pdf)
{
std::stringstream ss;
_target->htmlText(ss);
std::string out = ss.str();
std::string out_id = _target->id();
std::string out_parent_id = _target->parent()->id();
renderPdf(Wt::WString::tr(???), pdf);
}
void renderPdf(const Wt::WString& html, HPDF_Doc pdf)
{
HPDF_Page page = HPDF_AddPage(pdf);
HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
Wt::Render::WPdfRenderer renderer(pdf, page);
renderer.setMargin(2.54);
renderer.setDpi(96);
renderer.render(html);
}
};
// PDF изображения код
class SamplePdfResource : public Wt::WPdfImage
{
public:
SamplePdfResource(Wt::WObject *parent = 0)
: Wt::WPdfImage(400, 300, parent)
{
suggestFileName("line.pdf");
paint();
}
private:
void paint()
{
Wt::WPainter painter(this);
Wt::WPen thickPen;
thickPen.setWidth(5);
painter.setPen(thickPen);
painter.drawLine(50, 250, 150, 50);
painter.drawLine(150, 50, 250, 50);
painter.drawText(0, 0, 400, 300, Wt::AlignCenter | Wt::AlignTop, "Hello, PDF");
}
};
// Инициализация декартовой диаграммы
Wt::Chart::WCartesianChart* CreateCartesianChart(Wt::WContainerWidget* parent)
{
Wt::WStandardItemModel *model = new Wt::WStandardItemModel(PERFORMANCE_HISTORY, 2, parent);
//Create the scatter plot.
Wt::Chart::WCartesianChart* chart = new Wt::Chart::WCartesianChart(parent);
//Give the chart an empty model to fill with data
chart->setModel(model);
//Set which column holds X data
chart->setXSeriesColumn(0);
//Get the axes
Wt::Chart::WAxis& x_axis = chart->axis(Wt::Chart::Axis::XAxis);
Wt::Chart::WAxis& y1_axis = chart->axis(Wt::Chart::Axis::Y1Axis);
Wt::Chart::WAxis& y2_axis = chart->axis(Wt::Chart::Axis::Y2Axis);
//Modify axes attributes
x_axis.setRange(0, PERFORMANCE_HISTORY);
x_axis.setGridLinesEnabled(true);
x_axis.setLabelInterval(PERFORMANCE_HISTORY / 10);
y1_axis.setRange(0, 100);
y1_axis.setGridLinesEnabled(true);
y1_axis.setLabelInterval(10);
y2_axis.setRange(0, 100);
y2_axis.setVisible(true);
y2_axis.setLabelInterval(10);
//Set chart type
chart->setType(Wt::Chart::ChartType::ScatterPlot);
// Typically, for mathematical functions, you want the axes to cross at the 0 mark:
chart->axis(Wt::Chart::Axis::XAxis).setLocation(Wt::Chart::AxisValue::ZeroValue);
chart->axis(Wt::Chart::Axis::Y1Axis).setLocation(Wt::Chart::AxisValue::ZeroValue);
chart->axis(Wt::Chart::Axis::Y2Axis).setLocation(Wt::Chart::AxisValue::ZeroValue);
// Add the lines
Wt::Chart::WDataSeries s(1, Wt::Chart::SeriesType::LineSeries);
chart->addSeries(s);
//Size the display size of the chart, has no effect on scale
chart->resize(300, 300);
return chart;
}
Средство рендеринга PDF принимает строку HTML. Так что я думаю, что решение
renderPdf(WString::fromUTF8(out), pdf);