@@ -18,13 +18,13 @@ tags: ["pdf 生成","png 导出"]
1818
1919+  通过 html2canvas 、dom-to-image 等第三方库实现
2020+  通过 Puppeteer 启动一个 node 服务实现
21- +  < font   style = " color:rgb(51, 51, 51); " > canvas 原生绘制</ font > 
21+ +  canvas 原生绘制
2222
2323这些方式是真实项目会使用的方式,针对不同场景可以使用不同的方法,下面看一下每种方法如何实现、使用场景和优缺点,
2424
2525# 方案 1 - html2canvas  
2626
27- < font   style = " color:rgb(55, 65, 81); " > html2canvas 专门用于解析 DOM 结构及其关联的 CSS 样式,进而将网页内容渲染为 Canvas 元素的 JavaScript 库,下面是下载元素为 PNG 的示例代码:</ font > 
27+ html2canvas 专门用于解析 DOM 结构及其关联的 CSS 样式,进而将网页内容渲染为 Canvas 元素的 JavaScript 库,下面是下载元素为 PNG 的示例代码:
2828
2929``` typescript 
3030/** 
@@ -64,11 +64,11 @@ export const downloadDOMElementAsImage = async (elementId: string, fileName: str
6464};
6565``` 
6666
67- 通过 < font   style = " color:rgb(55, 65, 81); " > html2canvas ,我们封装了一个下载页面 DOM 为图片的方法,然后就可以很方便的调用方法进行页面元素的下载</ font > 
67+ 通过 html2canvas ,我们封装了一个下载页面 DOM 为图片的方法,然后就可以很方便的调用方法进行页面元素的下载
6868
69- ## < font   style = " color:rgb(55, 65, 81); " > 使用场景</ font >  
69+ ## 使用场景  
7070
71- < font   style = " color:rgb(55, 65, 81); " > 适用于需要将复杂的 DOM 结构(包括样式、背景图像、字体等)渲染为图片的场景。它可以捕获大部分 CSS 样式和 HTML 内容</ font > 
71+ 适用于需要将复杂的 DOM 结构(包括样式、背景图像、字体等)渲染为图片的场景。它可以捕获大部分 CSS 样式和 HTML 内容
7272
7373## 优缺点  
7474
@@ -155,7 +155,7 @@ export const downloadDOMElementAsImage = async (elementId: string, fileName: str
155155
156156可以看到使用也非常简单,我们可以通过 sc 参数来控制下载图片的清晰度和大小。
157157
158- ## < font   style = " color:rgb(55, 65, 81); " > 使用场景</ font >  
158+ ## 使用场景  
159159
160160如果对项目大小有要求,希望文本排版支持度高,需要稳定的文字、图片渲染能力或者处理结构化数据的能力,可以使用 dom-to-image
161161
@@ -164,9 +164,9 @@ export const downloadDOMElementAsImage = async (elementId: string, fileName: str
164164优点:
165165
166166+  库比较轻量
167- +  < font   style = " color:rgb(55, 65, 81); " > 适用于需要多格式导出的场景</ font > 
167+ +  适用于需要多格式导出的场景
168168
169- < font   style = " color:rgb(55, 65, 81); " > 缺点:</ font > 
169+ 缺点:
170170
171171+  需要手动处理跨域
172172
@@ -180,7 +180,7 @@ export const downloadDOMElementAsImage = async (elementId: string, fileName: str
180180+  兼容所有 css 
181181+  对项目体积有要求
182182
183- 那我们就可以使用 Puppeteer 来实现,它可以解决上面所有的问题。Puppeteer < font   style = " color:rgb(55, 65, 81); " > 是一个强大的 Node.js 库,用于控制 Chrome 或 Chromium 浏览器来帮我们生成想要的 PNG 或者 PDF,下面我们就使用 express + Puppeteer 来快速实现一个图片下载服务:</ font > 
183+ 那我们就可以使用 Puppeteer 来实现,它可以解决上面所有的问题。Puppeteer 是一个强大的 Node.js 库,用于控制 Chrome 或 Chromium 浏览器来帮我们生成想要的 PNG 或者 PDF,下面我们就使用 express + Puppeteer 来快速实现一个图片下载服务:
184184
185185``` javascript 
186186//  node 服务 app.js 示例代码
@@ -272,20 +272,20 @@ app.listen(PORT, () => {
272272
273273优点:
274274
275- +  高度还原视图:< font   style = " color:rgb(55, 65, 81); " > Puppeteer 使用的是无头 Chrome 浏览器,所以它生成的 PDF 和截图与用户在浏览器中看到的内容几乎完全一致</ font > 
276- +  < font   style = " color:rgb(55, 65, 81); " > 丰富的 API: Puppeteer 提供了超多 API,基本可以解决所有遇到的问题,相关文档地址:</font >[ https://github.com/puppeteer/puppeteer/blob/v1.5.0/docs/api.md ] ( https://github.com/puppeteer/puppeteer/blob/v1.5.0/docs/api.md ) ,非常多的 API
277- +  支持最新的 css:< font   style = " color:rgb(55, 65, 81); " > 由于 Puppeteer 使用的是 Chrome 浏览器,它支持所有现代 Web 特性,因此它在处理复杂网页时非常有优势 </ font > 
278- +  < font   style = " color:rgb(55, 65, 81); " > 跨域资源支持: Puppeteer 通常以无头模式运行,这种模式下浏览器跨域访问的限制会放宽</ font > 
275+ +  高度还原视图:Puppeteer 使用的是无头 Chrome 浏览器,所以它生成的 PDF 和截图与用户在浏览器中看到的内容几乎完全一致
276+ +  丰富的 API: Puppeteer 提供了超多 API,基本可以解决所有遇到的问题,相关文档地址:</font >[ https://github.com/puppeteer/puppeteer/blob/v1.5.0/docs/api.md ] ( https://github.com/puppeteer/puppeteer/blob/v1.5.0/docs/api.md ) ,非常多的 API
277+ +  支持最新的 css:由于 Puppeteer 使用的是 Chrome 浏览器,它支持所有现代 Web 特性,因此它在处理复杂网页时非常有优势 
278+ +  跨域资源支持: Puppeteer 通常以无头模式运行,这种模式下浏览器跨域访问的限制会放宽
279279
280- < font   style = " color:rgb(55, 65, 81); " > 缺点:</ font > 
280+ 缺点:
281281
282- +  需要部署服务:< font   style = " color:rgb(55, 65, 81); " > Puppeteer 需要在服务器端运行,需要一个后端环境来支持它。</ font > 
283- +  资源消耗大< font   style = " color:rgb(55, 65, 81); " > : 由于 Puppeteer 启动的是一个完整的 Chrome 浏览器实例,因此它的资源消耗相对较大,可能会影响服务器的性能 </ font > 
284- +  < font   style = " color:rgb(55, 65, 81); " > 额外的学习成本:如果团队都对 Puppeteer 不了解,可能需要额外的学习和维护成本</ font > 
282+ +  需要部署服务:Puppeteer 需要在服务器端运行,需要一个后端环境来支持它。
283+ +  资源消耗大: 由于 Puppeteer 启动的是一个完整的 Chrome 浏览器实例,因此它的资源消耗相对较大,可能会影响服务器的性能 
284+ +  额外的学习成本:如果团队都对 Puppeteer 不了解,可能需要额外的学习和维护成本
285285
286- < font   style = " color:rgb(55, 65, 81); " > 但是如果使用 Puppeteer 去生产环境使用,可能还会有同时处理大量请求导致服务资源被消耗光,甚至导致下载服务奔溃的情况,这时候我们就可以使用 puppeteer-cluster 来实现请求队列, 使用队列系统来管理请求,确保同时只处理一定数量的请求,其他请求则排队等待</ font > 
286+ 但是如果使用 Puppeteer 去生产环境使用,可能还会有同时处理大量请求导致服务资源被消耗光,甚至导致下载服务奔溃的情况,这时候我们就可以使用 puppeteer-cluster 来实现请求队列, 使用队列系统来管理请求,确保同时只处理一定数量的请求,其他请求则排队等待
287287
288- # < font   style = " color:rgb(55, 65, 81); " > 方案 3.2 - puppeteer-cluster</ font >  
288+ # 方案 3.2 - puppeteer-cluster  
289289
290290代码示例:
291291
@@ -381,15 +381,15 @@ process.on("SIGINT", async () => {
381381});
382382``` 
383383
384- 我们< font   style = " color:rgb(55, 65, 81); " >使用  puppeteer-cluster 创建了一个浏览器实例池,有如下优点:</ font > 
384+ 我们使用  puppeteer-cluster 创建了一个浏览器实例池,有如下优点:
385385
386- +  < font   style = " color:rgb(55, 65, 81); " > 可以更有效地处理并发请求,它会自动把接受的请求加入队列,保证所有请求都会进行处理。</ font > 
387- +  < font   style = " color:rgb(55, 65, 81); " > 将 PDF 和 PNG 生成的逻辑移到了 cluster.task 中,这样可以重用浏览器实例,提高效率</ font > 
388- +  < font   style = " color:rgb(55, 65, 81); " > 设置了最大并发数(maxConcurrency),可以根据服务器资源进行调整,避免资源耗尽</ font > 
386+ +  可以更有效地处理并发请求,它会自动把接受的请求加入队列,保证所有请求都会进行处理。
387+ +  将 PDF 和 PNG 生成的逻辑移到了 cluster.task 中,这样可以重用浏览器实例,提高效率
388+ +  设置了最大并发数(maxConcurrency),可以根据服务器资源进行调整,避免资源耗尽
389389
390- ** < font   style = " color:rgb(55, 65, 81); " > 注意:</ font > ** < font   style = " color:rgb(55, 65, 81); " > 在生产环境,我们可能需要在 puppeteerOptions 的 executablePath 设置具体的 chrome 路径,保证服务能找到 chorme</ font > 
390+ ** 注意:** 在生产环境,我们可能需要在 puppeteerOptions 的 executablePath 设置具体的 chrome 路径,保证服务能找到 chorme
391391
392- # < font   style = " color:rgb(55, 65, 81); " > 方案 4 - canvas 原生绘制</ font >  
392+ # 方案 4 - canvas 原生绘制  
393393
394394参考代码:
395395
@@ -422,7 +422,7 @@ img.src ='图片地址'
422422
423423canvas 虽然高性能,但是工作量大,一般生产环境不会使用
424424
425- # <font style="color:rgb(55, 65, 81);">总结</font> 
425+ # 总结 
426426
427427在实际开发中,面对不同场景我们会使用不同的方案,那我们公司的线上项目为例:在我们的「面试鸭」和「编程导航」的生成海报功能都是使用了 html2canvas 来生成海报,因为它要比 Puppeteer 快,能够让用户更快拿到海报图,在「老鱼简历」中,我们使用 Puppeteer 来导出简历,这样导出的简历和看到的更加一致,并且清晰度更加高。
428428
0 commit comments