找回密码
 快速注册
搜索
查看: 497|回复: 30

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

[复制链接]

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2022-2-9 07:43 |阅读模式
本帖最后由 hbghlyj 于 2022-2-24 12:24 编辑 在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>"
复制代码
参考资料:
stackoverflow.com/questions/15603491/how-to-make-html-pages-prin ... ent-size-from-chrome
developer.mozilla.org/en-US/docs/Web/CSS/@page/size

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

 楼主| hbghlyj 发表于 2022-2-9 08:07
好像找到了防止DIV被从中间切开分到两页的办法
stackoverflow.com/questions/907680/css-printing-avoiding-cut-in-half-divs-between-pages
@media print {   div {     break-inside: avoid;   } }

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

 楼主| hbghlyj 发表于 2022-2-9 08:33
本帖最后由 hbghlyj 于 2022-2-9 08:46 编辑 回复 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>"
复制代码
现在打印的话正好是1页!

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

 楼主| hbghlyj 发表于 2022-2-9 09:26
回复 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)
复制代码
这样就不会重新加载头部,页面也就不会闪了

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

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

830

主题

4862

回帖

3万

积分

积分
36159

显示全部楼层

isee 发表于 2022-2-9 23:13
回复 5# kuing


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

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

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

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

kuing 发表于 2022-2-16 18:16
回复 7# hbghlyj

怎么绑定嘀?

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

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

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

 楼主| hbghlyj 发表于 2022-2-16 23:15
回复 8# kuing
Javascript监听键盘事件keydown
回复 9# kuing
Element.scrollHeight 元素高度的度量

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

kuing 发表于 2022-2-17 00:31
回复 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>
复制代码

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

kuing 发表于 2022-2-18 16:11
回复 11# kuing

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

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

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

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

 楼主| hbghlyj 发表于 2022-3-23 03:54
回复 12# kuing
容易误点

我发现有一个onbeforeprint事件

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

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

kuing 发表于 2022-3-23 04:05
回复 14# hbghlyj

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

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

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

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

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


准备存了,又该研究一下这帖了😇

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

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-1-6 15:11
本帖最后由 abababa 于 2024-1-6 15:23 编辑
kuing 发表于 2024-1-5 16:00
准备存了,又该研究一下这帖了😇

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


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

730

主题

1万

回帖

9万

积分

积分
93613
QQ

显示全部楼层

kuing 发表于 2024-1-6 15:34
abababa 发表于 2024-1-6 15:11
有数据库的话,能不能这样,先列一个需要的帖子的号,好像就是网址上的那个tid=8569这样的,然后再列一个 ...

想法很好,只是实现起来恐怕很难啊🥺

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2024-1-6 15:55
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. })();
复制代码


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

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

手机版|悠闲数学娱乐论坛(第3版)

GMT+8, 2025-3-4 15:46

Powered by Discuz!

× 快速回复 返回顶部 返回列表