3

所以我希望能够在我们的数据库中为条目提供一个打印按钮,以便用户可以通过打印友好的“表单”打印条目。

我的想法是创建一个单独的页面,添加标签并让这些标签提取相关信息。

我知道我可以通过以下代码添加打开的小部件信息:

app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.TestPrint);

但我遇到了一些问题:

  1. 我无法让页面在新窗口中打开。这可能吗?

    window.open(app.pages.TestPrint);

只是给了我一个空白页。一旦新窗口打开,浏览器是否会丢失小部件源?

  1. 我无法获得打印选项(onClick 或 onDataLoad)来仅打印图像(或小部件)。我跑

    窗口.打印();

它包括标题+滚动条。我是否需要运行客户端脚本?

任何帮助,将不胜感激。谢谢!

4

4 回答 4

4

为了得到你想要的东西,你必须做很多工作。

这是我建议的更简单的答案:

不要打开新标签页。如果您像您提到的那样使用 showPage,并在页面上提供一个“后退”按钮以返回您所在的位置,您将获得几乎所有您需要的东西。如果您不想在打印时显示背面,那么您可以在打印之前在按钮上 setVisibility(false),然后打印,然后 setVisibility(true)。


我将简要介绍如何使用新选项卡执行此操作,但它非常复杂,因此如果不亲自尝试,我无法详细介绍。基本的想法是,你想用完整的 URL 打开页面,就像用户导航到它一样。

您可以使用#TestPrint 来指示要加载的页面。您还需要应用程序的 URL,据我所知,它仅在使用 Apps 脚本方法的服务器端脚本中可用:ScriptApp.getService().getUrl()。最重要的是,您可能需要传递密钥,以便您的页面知道要加载哪些数据。

因此,鉴于此,您需要通过调用服务器脚本来组装一个 url,然后将 key 属性附加到它。最后你想要一个类似的网址:

https://www.script.google.com/yourappaddress#TestPage?key=keyOfYourModel

然后在 TestPage 上,您需要读取密钥,并为该密钥加载数据。(您可以使用google.script.url读取密钥)。


或者,我认为您可以通过打开一个空白窗口然后直接写入其 DOM 来玩一些技巧,但我从未尝试过,而且由于 Apps 脚本在 iframe 内运行,我不确定它是否可能。如果我有机会我会玩它并更新这个答案,但为了您自己的参考,您可以在这里查看:create html page and print to new tab in javascript

我在想象类似的事情,除了你的页面写的是 html 内容。就像是:

var winPrint = window.open('', '_blank', 'left=0,top=0,width=800,height=600,toolbar=0,scrollbars=0,status=0');
winPrint.document.write(app.pages.TestPage.getElement().innerHTML);
winPrint.document.close();
winPrint.focus();
winPrint.print();
winPrint.close();

希望这三个选项之一有帮助:)

于 2017-01-31T01:36:06.583 回答
2

所以这就是我最终要做的。它并不优雅,但它有效。

我在用户编辑数据库条目时弹出的页面片段中添加了一个打印按钮。

数据库编辑按钮代码:

app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showDialog(app.pageFragments.FragmentName);

该打印按钮转到另一个(完整)页面并关闭片段。

打印按钮代码:

app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.ModelName_Print);
app.closeDialog();

我确保新的打印页面足够小,以便 Chrome 将其正确放入 8.5 x 11" 页面 (728x975)。

然后我创建了一个面板来填充页面并使用标签填充页面

@datasource.item.FieldName

然后我将以下内容放入面板的 onDataLoad

window.print();

所以现在当用户按下片段中的打印按钮时,他们会被带到这个新页面,并且在数据加载后,他们会自动获得一个打印对话框。

唯一的缺点是打印后用户必须使用我添加的后退按钮返回到数据库页面。

于 2017-01-31T01:57:18.753 回答
0

1.这是如何在弹出窗口中完成的,不会弄乱当前页面(客户端脚本):

function print(widget, title){
  var content=widget.getElement().innerHTML;
  var win = window.open('', 'printWindow', 'height=600,width=800');
  win.document.write('<head><title>'+title+'/title></head>');
  win.document.write('<body>'+content+'</body>');
  win.document.close(); 
  win.focus(); 
  win.print();
  win.close();
}  

按钮的 onclick 处理程序是:

print(widget.root.descendants.PageFragment1, 'test');

在此示例中,PageFragment1 是当前页面上的页面片段,通过添加具有名称hidden和定义的样式来隐藏.hidden{display:none;}(这与在应用制作工具中似乎从 DOM 中删除项目的可见不同)。完美运行...

2.您无法在另一个选项卡中打开应用程序中的页面。原则上,这样的事情会做到这一点:

var w=window.parent.parent;
w.open(w.location.protocol+'//'+w.location.host+w.location.pathname+'#PrintPage', '_blank');

但由于应用程序在距启动页面两层嵌套的框架中运行,并且来源不同,您将无法访问所需的 url(上述代码导致跨域框架访问错误)。因此,您必须对 URL 进行硬编码,该 URL 在部署时会发生变化,因此它会很快变得丑陋。无论如何,您都不想这样做,应用程序的加载时间应该会阻止您无论如何都想这样做。

于 2017-01-31T09:42:59.457 回答
0

1.

据我所知,您不能将 window.open 与 app.pages.* 结合使用,因为

window.open至少需要 url 参数,而 app.pages.* 本质上是 App Maker 提供的内部路由机制,它返回页面对象,适用于页面之间的切换,或打开对话框。

2.

您可能需要先设置页面样式,以便它包含您想要打印的内容。为此,请使用@media print

例如:我们在页面上有一个按钮,想从打印页面中隐藏它

@media print {  
  .app-NewPage-Button1 {   
     display : none;   
   } 
}

希望能帮助到你。

于 2017-01-31T01:22:59.620 回答