[英]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
作為路由參數。 這是用來檢索相關的document
從Documents
集合。 然后,通過對document.title
進行消毒來生成PDF filename
。用連字符替換所有空格。
現在設置了響應頭,以強制瀏覽器將PDF下載為帶有已清理filename
。
PDF是使用markdown-pdf
包從document.content
markdown生成的。 此過程由於兩個問題而變得復雜:
生成PDF的調用本質上是異步的,因此需要回調。 需要將其包裝到Meteor的Async.runSynch
方法中,以將其轉換為同步調用。 這將返回一個具有我們可以使用的result
屬性的對象。
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.