簡體   English   中英

如何使用Meteor從Markdown生成和下載PDF

[英]How do I generate and download a PDF from markdown using Meteor

我有一個Meteor文檔集合,其內容是使用markdown設置樣式的(有關如何執行此操作的示例,請參見: 如何將Markdown與Meteor一起實際使用

我的程序包堆棧如下:

npm

大氣層

查看文檔時,我想向我的用戶展示“以Download as PDF按鈕。 單擊此選項會將文檔的降價轉換為PDF文件,然后通過瀏覽器下載。

轉換過程受到限制; 它應在服務器上運行,但不允許將任何臨時文件保存到服務器。

我該如何實現?

使用iron-router ,創建服務器端路由以提供PDF。

Router.route '/api/pdf/:_id',
    name : 'generatePDF'
    where: 'server'
    action: ->
        document= Documents.findOne @params._id
        sanitize = Meteor.npmRequire 'sanitize-filename'
        filename = sanitize(document.title).replace(/\s+/g, '-')
        @response.writeHead 200,
            'Content-Type': 'application/pdf'
            'Content-Disposition': "attachment; filename=#{filename}.pdf"

        markdown = document.content
        Async.runSync (done)->
            Meteor.npmRequire('markdown-pdf')
            .from.string(markdown)
            .to.buffer (err, buffer)->
                done null, new BufferStream buffer
        .result.pipe @response

上面的路由接收_id作為路由參數。 這是用來檢索相關的documentDocuments集合。 然后,通過對document.title進行消毒來生成PDF filename 。用連字符替換所有空格。

現在設置了響應頭,以強制瀏覽器將PDF下載為帶有已清理filename

PDF是使用markdown-pdf包從document.content markdown生成的。 此過程由於兩個問題而變得復雜:

  1. 生成PDF的調用本質上是異步的,因此需要回調。 需要將其包裝到Meteor的Async.runSynch方法中,以將其轉換為同步調用。 這將返回一個具有我們可以使用的result屬性的對象。

  2. markdown-pdf軟件包具有to.buffer方法,該方法返回包含生成的PDF的buffer 這使我們可以將所有內容保留在代碼中,並且無需將臨時文件保存到服務器。 要將這個buffer傳遞到response我們需要將其轉換為流。 我使用輔助BufferStream對象為我完成此操作(請參見下文)

使用此路由后,我只需要在顯示模板上的某個位置放置“下載為PDF”按鈕(下面的代碼是Bootstrap 3類將Jade鏈接樣式化為按鈕)

a.btn.btn-primary(href='{{pathFor "generatePDF"}}' target='_blank') Download as PDF 

最后,這是BufferStream幫助器類:

stream = Meteor.npmRequire "stream" 

class @BufferStream extends stream.Readable 

    constructor: (@source, @offset = 0) ->
        throw new Meteor.Error 'InvalidBuffer', 'BufferStream source must be a buffer.' unless Buffer.isBuffer(@source)
        super
        @length = @source.length

    _read: (size) ->
        if @offset < @length
            @push @source.slice @offset, @offset + size
            @offset += size

        @push null if @offset >= @length

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM