【问题标题】:Save Openlayers map as PDF (offline version)将 Openlayers 地图另存为 PDF(离线版)
【发布时间】:2020-11-13 15:10:10
【问题描述】:

我想将我的 openlayers 地图保存为 PDF。

很遗憾,我尝试的所有选项都不起作用。

第一个选项,我猜这里是最简单的一个:

https://jsfiddle.net/Ljnya5gp/1/

我从中开发了这样的东西:

 function createPdf() {

 var doc = new jsPDF();

 source = $('#map')[0];

 specialElementHandlers = {
    '#map': function (element, renderer) {
        return true
    }
  };

 doc.fromHTML(
  source,
 15,
 15, 
 {
  'width': 170,
  'elementHandlers': specialElementHandlers
 }
   );
     doc.save('Area 5 map - alterations.pdf')

但脚本只为我下载空白文档。

我想下载这个部分(从 index.html)

      <div id="map">
        <div id="popup" class="ol-popup">
            <a href="#" id="popup-closer" class="ol-popup-closer"></a>
            <div id="popup-content"></div>
        </div>
      </div>

为什么输出的 PDF 文档是空白的?是不是嵌入到 HTML 文件中的 Map 脚本引起的?

我的&lt;div id="map"&gt; 将附加到 HTML 文件的脚本称为:

jsfiddle 可以在这里找到:

https://jsfiddle.net/rjetdvyo/

是不是也有问题的原因?

更新:

根据下面的答案,我形成了这样的东西:

函数 createPdf() {

var mapElement = $("#map");

html2canvas(mapElement, {
    useCORS: true,
    onrendered: function (canvas) {
        var img = canvas.toDataURL("image/jpeg,1.0");
        var pdf = new jsPDF();
        pdf.addImage(img, 'JPEG', 15, 40, 180, 180);
        pdf.save('a4.pdf')
    }
});
  }

 var map = (document.getElementById('map'), createPdf);

printpdf 按钮只刷新页面。

【问题讨论】:

    标签: javascript html pdf openlayers


    【解决方案1】:

    我认为一切正常,它显示为空白,因为您没有在 div 中写入任何文本。看看:

    function createPdf() {
    
        var doc = new jsPDF();
    
        source = $('#map')[0];
    
        specialElementHandlers = {
            '#map': function (element, renderer) {
                return true
            }
        };
    
        doc.fromHTML(
            source,
            15,
            15,
            {
                'width': 170,
                'elementHandlers': specialElementHandlers
            }
        );
        doc.save('Area 5 map - alterations.pdf')
    
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"
        integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg=="
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
    
    <div id="map">
        <div id="popup" class="ol-popup">
            <a href="#" id="popup-closer" class="ol-popup-closer">Hello</a>
            <div id="popup-content"><h1>Hello, this is a H1 tag</h1></div>
        </div>
    </div>
    
    <button onclick="createPdf()">generate PDF</button>

    Update:

    通过同时使用jsPDFhtml2canvas,您可以实现您的目标。

    html2canvas 从 DOM 元素创建一个画布对象。在画布上,您可以创建一个图像,最后通过jsPDF 将该图像转换为 pdf。看看下面的代码:

    function createPdf() {
    
        var mapElement = $("#map-canvas");
    
        html2canvas(mapElement, {
            useCORS: true,
            onrendered: function (canvas) {
                var img = canvas.toDataURL("image/jpeg,1.0");
                var pdf = new jsPDF();
                pdf.addImage(img, 'JPEG', 15, 40, 180, 180);
                pdf.save('a4.pdf')
            }
        });
    
    }
    
    // if HTML DOM Element that contains the map is found...
    if (document.getElementById('map-canvas')) {
    
        // Coordinates to center the map
        var myLatlng = new google.maps.LatLng(52.525595, 13.393085);
    
        // Other options for the map, pretty much selfexplanatory
        var mapOptions = {
            zoom: 14,
            center: myLatlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
    
        // Attach a map to the DOM Element, with the defined settings
        var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
    
    }
    #map-canvas {
        width: 500px;
        height: 400px;
    }
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"
        integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg=="
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"
        integrity="sha512-s/XK4vYVXTGeUSv4bRPOuxSDmDlTedEpMEcAQk0t/FMd9V6ft8iXdwSBxV0eD60c6w/tjotSlKu9J2AAW1ckTA=="
        crossorigin="anonymous"></script>
    
    <button onclick="createPdf()">generate PDF</button>
    <div id="map-canvas"></div>

    Update 2: 我不知道你遵循哪种方式。只需按照以下步骤完成工作:

    1. 先关注these steps
    2. 将您的 index.js 代码替换为:
    import 'ol/ol.css';
    import { Map, View } from 'ol';
    import TileLayer from 'ol/layer/Tile';
    import OSM from 'ol/source/OSM';
    
    const map = new Map({
        target: 'map',
        layers: [
            new TileLayer({
                source: new OSM()
            })
        ],
        view: new View({
            center: [0, 0],
            zoom: 0
        })
    });
    
    var exportButton = document.getElementById('export-pdf');
    
    exportButton.addEventListener(
        'click',
        function () {
            exportButton.disabled = true;
            document.body.style.cursor = 'progress';
    
            // var format = [297, 210]; 
            var resolution = 72; // The term 72 dpi(dots per inch) is used to express the resolution of a screen
            var dim = [297, 210]; // a4 size's dimension
            var width = Math.round((dim[0] * resolution) / 25.4);
            var height = Math.round((dim[1] * resolution) / 25.4);
            var size = map.getSize();
            var viewResolution = map.getView().getResolution();
    
            map.once('rendercomplete', function () {
                var mapCanvas = document.createElement('canvas');
                mapCanvas.width = width;
                mapCanvas.height = height;
                var mapContext = mapCanvas.getContext('2d');
                Array.prototype.forEach.call(
                    document.querySelectorAll('.ol-layer canvas'),
                    function (canvas) {
                        if (canvas.width > 0) {
                            var opacity = canvas.parentNode.style.opacity;
                            mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
                            var transform = canvas.style.transform;
                            // Get the transform parameters from the style's transform matrix
                            var matrix = transform
                                .match(/^matrix\(([^\(]*)\)$/)[1]
                                .split(',')
                                .map(Number);
                            // Apply the transform to the export map context
                            CanvasRenderingContext2D.prototype.setTransform.apply(
                                mapContext,
                                matrix
                            );
                            mapContext.drawImage(canvas, 0, 0);
                        }
                    }
                );
                var pdf = new jsPDF('landscape');
                pdf.addImage(
                    mapCanvas.toDataURL('image/jpeg'),
                    'JPEG',
                    0,
                    0,
                    dim[0],
                    dim[1]
                );
                pdf.save('map.pdf');
                // Reset original map size
                map.setSize(size);
                map.getView().setResolution(viewResolution);
                exportButton.disabled = false;
                document.body.style.cursor = 'auto';
            });
    
            // Set print size
            var printSize = [width, height];
            map.setSize(printSize);
            var scaling = Math.min(width / size[0], height / size[1]);
            map.getView().setResolution(viewResolution / scaling);
        },
        false
    );
    
    1. 将您的 index.html 替换为:
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>Using Parcel with OpenLayers</title>
        <style>
            #map {
                width: 400px;
                height: 250px;
            }
        </style>
    </head>
    
    <body>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
    
        <button id="export-pdf" >Export PDF</button>
        <div id="map"></div>
        <script src="./index.js"></script>
    
    </body>
    
    </html>
    

    【讨论】:

    • 是的,但我想要地图内容而不是 HTML 文本。那有可能吗?
    • 这是否意味着您希望将整个 div 保存为 pdf,其中 id 是 map?或者您正在向未保存的 div 显示地图?
    • 我需要将整个 Div 作为 PDF 格式保存在地图中
    • 是的整个 div。我需要地图。几乎是这样的:openlayers.org/en/latest/examples/print-to-scale.html 看着这个网站,你有 HTML 元素,还有嵌入的地图(javascript 代码)。可以导出为PDF吗?
    • @MKR,看看我更新的答案,让我知道这是否是你的答案。
    猜你喜欢
    • 2015-11-13
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 2011-01-27
    相关资源
    最近更新 更多