Может ли mxGraph экспортировать графики в формате PDF?
Я работаю над проектом, использующим mxGraph, где мне необходимо экспортировать вывод высокого разрешения в PDF для диаграммы процесса обслуживания. Я пытался воссоздать график с помощью JGraphX, клиента Java Swing и экспортировать его в PDF, но результат не близок к тому, что отображает браузер.
На клиенте нет экспорта PDF в JavaScript, есть ли у mxGraph явная поддержка генерации PDF из JavaScript?
1 ответ
Я объясню случай запроса, инициированного клиентом, когда диаграмма отображается в браузере при выполнении запроса. Это стандартный случай, mxGraph передает представление графа в XML-формате с использованием пользовательских графических примитивов, и они принимаются на сервере и декодируются бэкэндами Java или.NET.
Причиной необходимости отображения графика является то, что существуют определенные текстовые измерения, которые трудно воссоздать вне среды браузера.
На стороне клиента вам нужно создать необходимый немедленный XML, используя, например, пример diagrameditor.html в качестве руководства:
var exportImage = function(editor)
{
var graph = editor.graph;
var scale = graph.view.scale;
var bounds = graph.getGraphBounds();
// New image export
var xmlDoc = mxUtils.createXmlDocument();
var root = xmlDoc.createElement('output');
xmlDoc.appendChild(root);
// Renders graph. Offset will be multiplied with state's scale when painting state.
var xmlCanvas = new mxXmlCanvas2D(root);
xmlCanvas.translate(Math.floor(1 / scale - bounds.x), Math.floor(1 / scale - bounds.y));
xmlCanvas.scale(scale);
var imgExport = new mxImageExport();
imgExport.drawState(graph.getView().getState(graph.model.root), xmlCanvas);
// Puts request data together
var w = Math.ceil(bounds.width * scale + 2);
var h = Math.ceil(bounds.height * scale + 2);
var xml = mxUtils.getXml(root);
// Requests image if request is valid
if (w > 0 && h > 0)
{
var name = 'export.png';
var format = 'png';
var bg = '&bg=#FFFFFF';
new mxXmlRequest(editor.urlImage, 'filename=' + name + '&format=' + format +
bg + '&w=' + w + '&h=' + h + '&xml=' + encodeURIComponent(xml)).
simulate(document, '_blank');
}
};
куда editor.urlImage
URL-адрес генерирующего изображения сервлета, в случае с Java-сервером.
На стороне сервера, в случае Java, посмотрите файл java/examples/com/mxgraph/examples/web/ExportServlet.java. Это смотрит на параметр "format", переданный, и если 'pdf', writePdf()
метод вызывается.
Этот метод создает PdfWriter и визуализирует графические примитивы в Java Swing Graphics2D, используя привилегированную для Java часть mxGraph.
В этом примере результат PDF записывается непосредственно в ответ на ответ сервлета в этой строке:
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
Вы можете отобразить вывод в любой поток.
Обратите внимание, что вам нужно настроить iText для отображения каждого шрифта, который вам нужен в PDF. Это не всегда идеально для большого количества шрифтов. Стоит протестировать несколько случаев экспорта, чтобы убедиться, что выход достаточно хорош для ваших требований. В настоящее время мы исследуем использование PhantomJS для экспорта. Если экспорт Java недостаточно хорош, пожалуйста, опубликуйте еще один вопрос, касающийся использования PhantomJS, и я подробно опишу процесс для этого.
iText предоставляется в качестве примера библиотеки PDF для использования, это проще, поскольку он находится в библиотеке с открытым исходным кодом. Возможно, это не самая подходящая библиотека, нам было нелегко работать с этим конкретным сценарием. Возможно, вы также захотите изучить другие библиотеки Java PDF поколения.
Также обратите внимание, что серверная часть.NET поддерживает генерацию растровых изображений только в dotnet/aspnet/Export.ashx, там нет известной библиотеки PDF с открытым исходным кодом, чтобы предоставить в качестве примера.
Полное векторное решение:
- Задавать
mxClient.NO_FO = true;
- Экспорт SVG в PDF с помощью svg2pdf.js
- Запишите весь текст DIV в pdf с помощью jsPDF
Пример:
let pdf = new jsPDF('p', 'pt', 'a4', false, false);
mxClient.NO_FO = true;
let graph = Draw(drawdiv, false);
let svgEl = drawdiv.children[1];
//draw svg:
svg2pdf(svgEl, pdf, {
xOffset: pdfPageDefaultOffsetX,
yOffset: pdfOffsetY,
scale: divToPdfRatio
});
//draw text:
for (let child of drawdiv.children) {
if (child.tagName === 'DIV') {
let splitText = pdf.splitTextToSize(child.innerText, Math.ceil((childSizes.width) * divToPdfRatio));
pdf.text(pdfPageDefaultOffsetX + (child.offsetLeft * divToPdfRatio), textPositionTop, splitText, {
align: child.style.textAlign,
lineHeightFactor: 1,
});
}
}
pdf.save('Test.pdf');