在我的应用程序中,我有一些应该可以打印的视图.您可以将它们视为报告.我在服务器端生成HTML.

当用户单击"Print"按钮时,我调度API调用,以文本形式检索呈现的html,将其放入<iframe>中,然后在结果窗口上调用print().

在Chrome和Firefox(台式机)上,这是可行的(或多或少...)

但在Chrome手机(安卓)上的行为是very%奇怪的.API调用被正确调度,"系统"打印模式打开,但显示的不是IFRAME内容,而是用于打印的"父"页面内容(包含"打印"按钮的页面).

这就好像我呼叫print()的iFrame不是移动设备上的正确窗口.我已经判断了Android上的远程开发人员控制台,没有错误或其他消息可以给我任何提示.

如果有帮助,下面是我在服务中使用的代码,用来生成包含可打印内容的iframe:

return this._api.printEntity(entity).pipe(
  tap(data => {
    const iframe: HTMLIFrameElement = document.createElement('iframe');
    document.body.appendChild(iframe);

    const printWin: Window = iframe.contentWindow!;
    printWin.document.write(data);
          
    setTimeout(() => {
      printWin.focus();
      printWin.print();
      printWin.close();
      document.body.removeChild(iframe);
    }, 1000);
  })
);

正如您可能注意到的,我使用了very个较大的超时时间,以便让iframe有足够的时间在生成的报告中加载样式文件和图像.我试过使用printWin.onload ETC,但我不能让它工作.

我很难相信,这么简单的任务看起来如此繁琐,我有什么遗漏的吗?

推荐答案

在有人拿出更好的解决方案之前,以下是我解决它的方法. 实际上有多个步骤,我想它们的结合帮助我解决了这个问题:

  • 确保下载的HTML文件不包含任何必须加载的链接(样式、图像).这(至少我认为是这样)确保了iframe立即准备好,这样在所有请求都通过之前,我就不必费力地处理超时了.
  • 下载HTMLas file.通过下载它,将其转换为文件,创建一个对象URL,并将其设置为iframe src,我就能够在移动浏览器上打印.我只是简单地对从字体到图像的所有内容进行了Base64编码.这还有一个额外的好处,那就是可移植性更强.尤其是如果您的图像/数据只有经过身份验证的用户才能访问.
  • 使用onafterprint从DOM after打印中删除IFRAME.否则,打印屏幕为空白.

下面是我的print方法现在的样子,没有任何问题:

public printEntity(entity: TEntity): Observable<void> {
      return this._http.get('yourUrlHere', {responseType: 'blob', observe: 'response'}).pipe(
        tap((res: any) => {
          const blob: Blob =  new Blob([res.body], {type: 'text/html'});
          const fileURL = URL.createObjectURL(blob);
          const iframe: HTMLIFrameElement = document.createElement('iframe');
          iframe.src = fileURL;
          document.body.appendChild(iframe);

          const printWin: Window = iframe.contentWindow!;
          printWin.print();
          printWin.onafterprint = () => { printWin.close(); document.body.removeChild(iframe); };
          
        }),
        switchMap(_ => of()),
      );

Html相关问答推荐

HTML图像无法正确放大和缩小规模

如何使div按钮链接到另一个网页

Div内容防止同级大小增加

与窗高匹配的响应式正方形网格

如何设计缠绕锚点元素的样式?

错误时交换表单,成功时使用HTMX重定向

(HTML框架标签)点击后目标框架将不再工作

为什么带有截断的 contentedible div 在受约束时会在 Chrome 中添加空格

如何使用 HTML 将对象数组发送到 Nodejs Express

当我们在vue中使用截断大文本时如何显示标题属性?

在DIV上应用梯度模糊未如预期工作

需要帮助个性化我的 CSS 导航栏:如何在鼠标悬停时突出显示
  • 元素?
  • 您如何动态更改 Vue 中更高级别的标签的 CSS

    重点/主动输入的概述问题

    两部分问题 - 是什么导致了这个空白?

    font awesome 的 CDN/CSS 如何工作?

    不理解 CSS 中的 General sibling combinator (~)

    绝对定位的 div 与另一个静态定位的 div 的边距顶部一起移动

    CSS 网格自动高度不适用于特定网格区域

    禁用的 Select 标签没有在 chrome 上的 css 中指定的 colored颜色