2015-06-30 102 views
8

我有一個網頁,它是一個動態生成的SVG文檔。 Javascript例程基本上構建了SVG的DOM。閱讀器可以通過點擊導致sVG改變的各種「按鈕」或對象來操作文檔。 (雖然沒有動畫)動態生成SVG的高分辨率打印輸出

我希望讀者能夠打印出大幅面,高分辨率的文檔圖像。我怎樣才能做到這一點?

正常情況下,文檔被縮放並裁剪以適合屏幕。我可以生成一個巨大的圖像,但然後瀏覽器會裁剪它。

要了解我的意思是高分辨率,屏幕圖像通常爲每英寸89像素,可能爲11 x 16「左右,大幅面圖像可以很容易地爲每英寸600像素,即36我不知道如何生成這樣的打印輸出

有沒有一種方法可以從動態生成的DOM生成狀態SVG標記文檔?如果是這樣,我可以將靜態SVG轉換爲PDF和然後打印PDF

+0

如果您將大小應用於所需大小的SVG,並使用此代碼http://www.cloudformatter.com/CSS2Pdf,則可以從瀏覽器執行此操作。當你調用API時,你設置頁面大小,它會把你的SVG放在這個大小的div中併發送給PDF引擎。如果你想離線使用,那麼XSL FO產品應該沒有問題渲染一個幾乎任何大小的SVG。 –

回答

2

你應該能夠使用XMLSerializer轉換你的SVG在它的修改狀態,並且允許用戶直接用他們的瀏覽器打開或保存這個SVG文檔

瀏覽器應該從svg提供高質量的打印。

+0

當我這樣做時,它只是複製HTML頁面,包括JavaScript代碼。它沒有呈現SVG的動態狀態。 –

1

我們有一個具有相同情況的應用程序。 SVG是在我們的Java應用程序的框架中構建和操作的。但所有的SVG操作都發生在JavaScript中。我們打印的內容是通過svg標籤進行循環,然後構建一個只有svg文件的文件,該文件將在瀏覽器中打開。將文件命名爲FileName.svg並將其提供給瀏覽器。然後你可以使用瀏覽器進行打印。

這是要創建的文件的格式。

<?xml version="1.0" encoding="utf-8"?> 
<svg 
    xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"> 

    svg elements go here 

</svg> 

下面是一些代碼片段的幫助。

// function to export as image, document, or print (SVG) 
function exportSVGas(exFormat, frName) { 
    var exHeight = window.parent.document.getElementById('canvasMainFrame' + frName).offsetHeight; 
    var exWidth = window.parent.document.getElementById('canvasMainFrame' + frName).offsetWidth; 
    var exSvg = '<svg xmlns=\"' + svgNS + '\" xmlns:xlink=\"' + xlkNS + '\" xmlns:ifp=\"' + ifpNS + '\" version=\"1.1\" '; 
    exSvg = exSvg + 'height=\"' + exHeight + 'px\" width=\"' + exWidth + 'px\" >'; 
    if (exFormat.toLowerCase() == 'SVG'.toLowerCase()) { 
     exSvg = exSvg + '<script type=\"text/javascript\">if(window.addEventListener){window.addEventListener(\"load\",function(){setTimeout(\"window.print()\",500);},false);}else if(window.attachEvent){window.attachEvent("onload", function(){setTimeout(\"window.print()\",500);},false);}</script>'; 
    } 
    // serialize by group 
    var groups = getChildren(document.getElementsByTagName('svg')[0], 'g'); 
    for (var i = 0; i < groups.length; i++) { 
     exSvg = exSvg + serializeXmlNode(groups[i]); 
    } 
    exSvg = exSvg + '</svg>'; 
    // remove hidden groups or elements 
    var exXml = $.parseXML(exSvg); 
    $exXml = $(exXml); 
    var exGroups = document.getElementById('layersgroup').getElementsByTagName('g'); 
    for (var i = 0; i < exGroups.length; i++) { 
     var exGroup = exGroups[i]; 
     var exId = exGroup.getAttribute('id'); 
     var exVisible = exGroup.getAttribute('visibility'); 
     if (exVisible == 'hidden') { 
      $exXml.find('#' + exId).remove(); 
     } 
    } 
    $exXml.find('#transform-buttons').removeAttr('transform'); 

    exSvg = serializeXmlNode($exXml[0]); 
    //needs url of svg from javascript to provide context to "url()" function in export 
    window.parent.notify('exportSVG', exFormat, exSvg, document.URL); 
} 

// helper function 
function serializeXmlNode(xmlNode) { 
    if (typeof window.XMLSerializer != "undefined") { 
     return (new window.XMLSerializer()).serializeToString(xmlNode); 
    } else if (typeof xmlNode.xml != "undefined") { 
     return xmlNode.xml; 
    } 
    return ""; 
} 

如果您發現它需要較大的打印量,您會希望將它放在一個組中,然後對該組進行縮放變換。這樣你就可以做到2 3或4倍。像這樣的東西。

<svg> 
    <g transform="scale(2)"> 
    <g> 
</svg> 

但作爲對我們來說,顯示8" ×8" ,在瀏覽器將打印精細到C尺寸紙張。我認爲這是SVG的本質。但正如您所提到的,您也可以嘗試PDF路由,因爲PDF將SVG視爲可擴展的。我們的應用程序是Java,因此我們使用Apache Batik進行PDF導出。祝你好運。

0

我見過的用於導出動態創建的SVG元素的最佳實現是由紐約時報團隊開發的SVG-Crowbar 2。使它特別有用的是它獲取應用於svg元素的外部css規則。

我會在你的情況下做的是安裝Crowbar到你的瀏覽器,看看導出的svg文件是什麼樣子。如果它看起來不錯,你可以寫一段代碼,

  1. 複製到頁面的主體有用元素
  2. 使用撬棍功能,內聯CSS添加到複製的元素
  3. 使用XMLSerializer來形成複製svg元素的字符串
  4. 的Base64編碼使用btoa或這樣
  5. 該字符串使用隱藏form
  6. 具有圖像提交給服務器後端解碼字符串並將內容發送迴文件:mime type image/svg+xmlContent-Disposition: attachment; filename=yourfile.svg

您還可以嘗試保存該文件而不會往返服務器,但瀏覽器支持因此類方法而異。

+0

XMLSerializer似乎沒有序列化動態創建的DOM元素。 –

+0

@TylerDurden:不知道你的意思。只要svg元素在DOM中,您應該可以從中導出一個字符串。例如,之後會創建[此Codepen](http://codepen.io/amergin/pen/qdoezZ)中的'clone',並且控制檯輸出是序列化字符串。 – amergin