首页 > 解决方案 > 将 Openlayers 地图另存为 PDF(离线版)

问题描述

我想将我的 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 脚本引起的吗?

<div id="map">将附加到 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 按钮仅刷新页面。

标签: javascripthtmlpdfopenlayers

解决方案


我认为一切都很好,它显示为空白,因为您没有将任何文本写入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 元素创建一个画布对象。在画布上,您可以创建一个图像,最后将该图像转换为 pdf 格式jsPDF。看看下面的代码:

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. 首先按照以下步骤操作。
  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>

推荐阅读