Forgot password?
 Create new account
View 662|Reply 30

以任意的页面大小打印网页

[Copy link]

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

hbghlyj Posted at 2022-2-9 07:43:35 |Read mode
Last edited by hbghlyj at 2022-2-24 12:24:00在Chrome的打印对话窗中,页面尺寸只有预设的几种选项,而且分页会导致一些元素的分离,比如公式的一半在前一页,另一半在后一页的这种情况.
解决办法:打开控制台,在文件系统中新建一个css样式表(我发现,在这里书写的css规则会实时地起作用,比如写一个*{display:none}然后立马就看到所有元素消失了).写入以下css规则:
@page {
    size: 297mm 210mm; /* landscape */
    /* you can also specify margins here: */
    margin: 25mm;
    margin-right: 45mm; /* for compatibility with both A4 and Letter */
  }
}

Screenshot 2022-02-08 233457.png
然后再打印,就发现,选择页面尺寸的选项消失了,Chrome会遵守css中规定的尺寸来打印.
为了打印为单页pdf(防止公式被切开),我们需要把所有元素打印到一页上(如果网页很长就是一个很长的页),那么可以用document.body.scrollHeight获取(包括视窗外的区域)页面总高度,用document.body.scrollWidth获取宽度.
最后得到的代码为:
  1. document.head.innerHTML+="<style>@page{margin:0;size:"+document.body.scrollWidth+"px "+document.body.scrollHeight+"px}</style>"
Copy the Code
参考资料:
stackoverflow.com/questions/15603491/how-to-m … ent-size-from-chrome
developer.mozilla.org/en-US/docs/Web/CSS/@page/size

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2022-2-9 08:07:17
好像找到了防止DIV被从中间切开分到两页的办法
stackoverflow.com/questions/907680/css-printi … f-divs-between-pages
@media print {   div {     break-inside: avoid;   } }

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2022-2-9 08:33:40
Last edited by hbghlyj at 2022-2-9 08:46:00回复 1# hbghlyj
把margin设为0以后还是会纵向溢出一点点也不知道什么原因
好像是dpi的问题:屏幕上的1px(1像素)不等于打印出来的1px !
做了一个测试,我这边屏幕上10000px对应于打印出来的2646mm,将1#的代码改为
  1. document.head.innerHTML+="<style>@page{margin:0;size:"+(document.body.scrollWidth*0.2646)+"mm "+(document.body.scrollHeight*0.2646)+"mm}</style>"
Copy the Code
现在打印的话正好是1页!

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2022-2-9 09:26:12
回复 3# hbghlyj
页面的头部里面有很多东西,如果用3#的代码的话,页面的头部会重新加载,所以会闪一下,不如改为
  1. st=document.createElement("style");st.innerHTML="@page{margin:0;size:"+(document.body.scrollWidth*0.2646)+"mm "+(document.body.scrollHeight*0.2646)+"mm}";document.head.appendChild(st)
Copy the Code
这样就不会重新加载头部,页面也就不会闪了

701

Threads

110K

Posts

910K

Credits

Credits
94167
QQ

Show all posts

kuing Posted at 2022-2-9 17:16:34
先 mark 一下,明年存懒人版撸题集时(如果论坛还存在)再研究一下这帖

801

Threads

4889

Posts

310K

Credits

Credits
36169

Show all posts

isee Posted at 2022-2-9 23:13:25
回复 5# kuing


这才明白,我还纳闷,通常打印纸不是A3,A4,B5么。。。。。

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2022-2-11 12:45:14
回复 6# isee
是虚拟打印...只是为了保存为pdf,可以作为邮件附件等等
另外,我刚才把4#的代码绑定在Ctrl+P快捷键上了,这样的话,按下Ctrl+P快捷键就会首先自动设置页面尺寸,再弹出打印窗口.

701

Threads

110K

Posts

910K

Credits

Credits
94167
QQ

Show all posts

kuing Posted at 2022-2-16 18:16:12
回复 7# hbghlyj

怎么绑定嘀?

701

Threads

110K

Posts

910K

Credits

Credits
94167
QQ

Show all posts

kuing Posted at 2022-2-16 18:18:17
有时候,如果只想打印 1~n 楼,后面想忽略掉,如何获取第 n 楼对应的高度?

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2022-2-16 23:15:52
回复 8# kuing
Javascript监听键盘事件keydown
回复 9# kuing
Element.scrollHeight 元素高度的度量

701

Threads

110K

Posts

910K

Credits

Credits
94167
QQ

Show all posts

kuing Posted at 2022-2-17 00:31:41
回复 10# hbghlyj

我在论坛试一下:
现在每层楼的下方那条分界线已变成可点击。
点击那条线,就会设置 @page 的宽为那条线的宽,高度为那条线与文档顶端的距离。
然后按打印,页底就会到那条线上,虽然有点误差,不过影响不大。
最后再改打印选项为只打印第1页,这样就实现了 9# 想要的。(这步不知是否也可以用 css 或 js 实现?

当前实现代码如下:
  1. <script>
  2. //===设置打印到哪
  3. var threadads = document.getElementsByClassName('threadad');
  4. for (let item of threadads) {
  5.     item.setAttribute("onclick","printto(this)");
  6.     item.style="cursor:pointer";
  7. }
  8. function printto(ts){
  9.     var ww = ts.scrollWidth;
  10.     var hh = ts.getBoundingClientRect().bottom  + window.scrollY;
  11.     var st = document.createElement("style");
  12.     st.innerHTML = "@page{size: " + ww + "px " + hh + "px; margin:0;}";
  13.     document.head.appendChild(st);
  14. }
  15. </script>
Copy the Code

701

Threads

110K

Posts

910K

Credits

Credits
94167
QQ

Show all posts

kuing Posted at 2022-2-18 16:11:23
回复 11# kuing

干脆进一步将 setAttribute("onclick","printto(this)") 改成 setAttribute("onclick","printto(this);print()") ,点击就打印到那里
(缺点就是有时会造成误点)

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2022-2-18 20:35:38
回复 11# kuing
这步不知是否也可以用 css 或 js 实现?
可以把往下的部分设为隐藏(display:none),然后打印,然后再改回来

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2022-3-23 03:54:20
回复 12# kuing
容易误点

我发现有一个onbeforeprint事件

在地址栏输入chrome.print可以直接打印!但是做成链接就无法打印

701

Threads

110K

Posts

910K

Credits

Credits
94167
QQ

Show all posts

kuing Posted at 2022-3-23 04:05:46
回复 14# hbghlyj

刚躺下,明天再改回去。
的确我也误点过几次,但是一直懒得理

3146

Threads

8493

Posts

610K

Credits

Credits
66158
QQ

Show all posts

 Author| hbghlyj Posted at 2022-3-23 04:08:51
回复 15# kuing
onbeforeprint可以弄一个prompt()弹窗,输入需要打印到的楼层数,然后把其他楼层设隐藏,然后onafterprint再显示出来

701

Threads

110K

Posts

910K

Credits

Credits
94167
QQ

Show all posts

kuing Posted at 2024-1-5 16:00:34
kuing 发表于 2022-2-9 17:16
先 mark 一下,明年存懒人版撸题集时(如果论坛还存在)再研究一下这帖
准备存了,又该研究一下这帖了😇

唉本来应该在 12 月搞定,结果又拖到 2024 啦,越来越懒了😔

418

Threads

1628

Posts

110K

Credits

Credits
11891

Show all posts

abababa Posted at 2024-1-6 15:11:57
Last edited by abababa at 2024-1-6 15:23:00
kuing 发表于 2024-1-5 16:00
准备存了,又该研究一下这帖了😇

唉本来应该在 12 月搞定,结果又拖到 2024 啦,越来越懒了😔 ...
有数据库的话,能不能这样,先列一个需要的帖子的号,好像就是网址上的那个tid=8569这样的,然后再列一个需要的楼层的号,好像是pid,然后就是
tid=8569,pid=43047,43057,57407,
tid=...,pid=...
这样一行一行的,最后从数据库里读出来整个的内容,弄成pdf。
就是弄pid的时候,应该能用javascript弄一个按钮,点一下帖子的那个按钮,就能让它追加进去,最后一个帖子就只点按钮就行了。
然后楼层的pid那个,其实也不用怕多点和顺序,因为追加之后,只要删除重复的,再排序,就是正常的顺序了,虽然它不是楼层值,但也是和楼层一样,是从小到大的顺序。

701

Threads

110K

Posts

910K

Credits

Credits
94167
QQ

Show all posts

kuing Posted at 2024-1-6 15:34:06
abababa 发表于 2024-1-6 15:11
有数据库的话,能不能这样,先列一个需要的帖子的号,好像就是网址上的那个tid=8569这样的,然后再列一个 ...
想法很好,只是实现起来恐怕很难啊🥺

418

Threads

1628

Posts

110K

Credits

Credits
11891

Show all posts

abababa Posted at 2024-1-6 15:55:54
kuing 发表于 2024-1-6 15:34
想法很好,只是实现起来恐怕很难啊🥺
就是用油猴的话,用下面的javascript
  1. // ==UserScript==
  2. // @name         New Userscript
  3. // @namespace    http://tampermonkey.net/
  4. // @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js
  5. // @version      0.1
  6. // @description  try to take over the world!
  7. // @author       You
  8. // @match        https://kuing.cjhb.site/*
  9. // @grant        none
  10. // ==/UserScript==
  11. (function() {
  12.         'use strict';
  13.         $(document).ready(function(){
  14.                 var set = new Set();
  15.                 $('body').click(function(event){
  16.                         var pid = $(event.target);
  17.                         pid = $(pid).attr('id').replace('postmessage_','');
  18.                         set.add(pid);
  19.                 });
  20.                 $('#hd').click(function() {
  21.                         var arr = Array.from(set);
  22.                         arr.sort();
  23.                         console.log(arr);
  24.                 });
  25.         });
  26. })();
Copy the Code


就能把这个主题里的所有需要的帖子都弄出来,就是点每个需要的楼层里任意的正常文字,不能是加粗或者代码什么的。然后全点完了,回到最上面,点一下那个背景图的任意地方,就能在浏览器里输出所有需要的pid,第一楼其实也有pid,在那个table的td里面。

但只这个能弄第一页,下一页就变成新的了,所以我想能不能直接存到什么地方,然后下一页其实还是这个tid,就追加进这个tid里。然后这个开启的话,页面上的按钮什么的一点击就都执行这个了,就不好使了,需要变正常的话,还得关闭油猴。要是懂javascript的应该能写得更完善。

手机版Mobile version|Leisure Math Forum

2025-4-20 22:00 GMT+8

Powered by Discuz!

× Quick Reply To Top Return to the list