0

在收到来自客户端的请求后,我正在使用 jsreport core 生成 pdf,然后将文件发送给客户端,如下所示:

  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', 'attachment; filename=test.pdf');
  jsreport.render(form).then(response => response.stream.pipe(res));

现在我想在客户端下载文件,方法是从请求中获取结果字符串并将其转换为 blob,然后将 blob 转换为 URL,但我得到的结果文件是空的,我相信这是因为结果从 pdf 字符串生成的 url 太长了……有没有人对使用 javascript 在浏览器中下载生成的文件有任何建议?

4

1 回答 1

3

从您的客户端/前端代码,您将需要通过执行基于表单的发布请求来调用 jsreport 服务器,浏览器需要该请求来启动下载对话框。

您可以将此实用程序代码(取自 jsreport 浏览器 sdk 源代码)放在您自己的代码中的某个位置。

function download (serverUrl, filename, request) {
  var requestValues = Object.assign({}, request)

  requestValues.options = requestValues.options || {}
  requestValues.options['Content-Disposition'] = 'attachment;filename=' + filename

  return render(serverUrl, requestValues)
}

function render (serverUrl, request) {
  var frameName = placeholder || '_blank'
  var mapForm = document.createElement('form')
  mapForm.target = frameName
  mapForm.id = new Date().getTime()
  mapForm.method = 'POST'
  mapForm.action = serverUrl

  function addInput (form, name, value) {
    var input = document.createElement('input')
    input.type = 'hidden'
    input.name = name
    input.value = value
    form.appendChild(input)
  }

  function addBody (path, body) {
    if (body === undefined) {
      return
    }

    for (var key in body) {
      if (isObject(body[key])) {
        // somehow it skips empty array for template.scripts, this condition fixes that
        if (body[key] instanceof Array && body[key].length === 0) {
          addInput(mapForm, path + '[' + key + ']', [])
        }
        addBody(path + '[' + key + ']', body[key])
      } else {
        if (body[key] !== undefined && !(body[key] instanceof Array)) {
          addInput(mapForm, path + '[' + key + ']', body[key])
        }
      }
    }
  }

  addBody('template', request.template)

  if (request.options != null) {
    addBody('options', request.options)
  }

  if (request.data) {
    addBody('data', request.data)
  }

  var headers = {}
  headers['host-cookie'] = document.cookie
  addBody('headers', headers)

  document.body.appendChild(mapForm)

  function submit (i) {
    if (i > 10) {
      return console.log('Unable to submit render form.')
    }
    try {
      mapForm.submit()
      mapForm.outerHTML = ''
    } catch (e) {
      setTimeout(function () {
        submit(i + 1)
      }, 50)
    }
  }

  submit(0)
}

然后像这样使用它(当然你需要更新http://localhost:5488/your-report-route到你的服务器工作的真实网址)。

download('http://localhost:5488/your-report-route', 'newfile.pdf', {
  template: {
    // your options here
  },
  data: {
    // your data here
  }
})
于 2018-01-19T16:56:59.057 回答