关于pdf:使用-PDF-Ai-GPT-工具获得-PDF-文件的内容摘要

龙年春节初七,OpenAI 的文字生成视频的模型 Sora 公布,微信公众号和知乎 AI 畛域涌现了大量介绍 Sora 的文章。 我是一个技术类文章创作者,Sora 的性能仿佛对我没有太大帮忙,还是老老实实钻研如何用 ChatGPT 来提供本人的写作效率吧。 我之前公布的文章:聊聊 SAP 原版技术书籍系列之三:SAP Business Technology Platform,文章开端介绍了这本书试读版的摘要,就是 ChatGPT Store 里一个名叫 PDI Ai PDF 的工具生成的。 这个工具在 ChatGPT Store 的 PDF 搜寻关键字排名名列第一,有60万次以上的使用量。 我最先间接把 PDF 通过附件的形式上传到 GPT 输出 Prompt 的中央,而后收到提醒,须要把这个 PDF 上传到一个叫做 myaidrive.com 的网站,而后把生成的链接给它,它就能够依据此链接来检索 PDF 的内容。 AI Drive 是一个相似 Google Drive 的网站,上传 PDF 之后,生成一个 url: 我把这个 url 连同 Prompt 一起发送给它: 很快我就收到了这个 PDF 的内容摘要: 这个PDF的前15页内容涵盖了对于SAP Business Technology Platform (SAP BTP)的应用案例辨认、翻新类型、以及如何利用SAP Activate办法辨认业务流程中的缺口,并思考可扩展性选项。以下是依据您的要求,按要点合成的概要:应用案例辨认:文档探讨了SAP BTP如何提供不同的能力,并通过应用案例模式帮忙辨认特定于业务环境的应用案例。通过一个对于Rocking Gas公司的故事引入,展现了如何在数字转型我的项目中思考SAP BTP的价值提案,并强调了在过来几个月中SAP BTP的应用有余及其后劲的开释。(浏览样本, 页 2)翻新类型:具体探讨了SAP BTP能够解决的不同业务问题区域,如性能扩大、触达扩大、过程翻新、过程自动化、跨产品工作流、跨性能业务流程、机器学习和物联网(IoT)。每种翻新类型都具体阐明了通过SAP BTP如何实现,并通过具体例子说明了每种类型的利用。(浏览样本, 页 3-4)利用SAP Activate辨认业务缺口:强调了如何应用SAP Activate办法辨认业务流程中的缺口,这是施行SAP S/4HANA和SAP S/4HANA Cloud我的项目的关键步骤。文档解释了fit-to-standard练习的重要性,以及如何通过配置积压工作和集成与扩大需要的辨认来实现业务需要。(浏览样本, 页 11)可扩展性概念:探讨了在SAP S/4HANA施行中,通过扩大来满足业务需要的不同办法。包含利用内扩大和侧边扩大两种次要技术,以及它们如何帮忙在不同的业务场景中实现性能扩大。(浏览样本, 页 13-14)我的微信公众号文章,如果蕴含了 AI 生成的文字,我会专门注明。 ...

February 22, 2024 · 1 min · jiezi

关于pdf:对比几家比较优质的PDF转Word-SDK

Hello 大家好,我是小瘪三。咱们打工人平时办公免不了要对一些文档格局行转换。咱们将探讨几款支流的 PDF 转 Word SDK,剖析它们在咱们打工人的理论工作中所出现的劣势与劣势。 Solid:老牌的 PDF to Office 转档库,有几十年的积攒。Aspose: 反对十分多的文件格式互转,也蕴含PDF 转 word 。Foxit:自主研发 PDF,PDF to Office 也是最近刚推出的。ComPDFKit: 最近一家新锐公司,更新频率很高。补充一下谢谢话不多说,间接比照一下 PDF 转 word 的成果。比照表:我别离筛选了一些不同特色的文档进行测试,其中包含页数多,蕴含表格,图文混排。波及到论文,cad制图,金融等畛域,先看一下这些文档的转档耗时。 12个文档中,foxit 有三个文档没有转换胜利,其余三个 SDK 全副文档都转换胜利了。Aspose SDK 因为试用起因只能转换前4页,然而有些状况下比照其余三个转了全副页面的速度还慢。综合下来ComPDFKit的转换速度最快。接下来咱们看一下具体成果。 成果文档 - 651页文档.pdf原文档: 各SDK厂商转档比照 ComPDFKit:根本没啥问题,然而字体和原文档有区别 foxit:能够看到会有一些小的辨认谬误,次要在跨行的时候,存在局部粗体辨认谬误的状况 Solid: 根本也没啥问题,没什么谬误,不过也存在字体区别。 成果文档 - 证券文档.pdf原文档: 各SDK厂商处理结果: ComPDFKit: 整体排版正确,第二页的局部字体会呈现拖影景象,局部文字会呈现超出文本框的景象。foxit:整体排版正确,第二页的局部字体会呈现拖影景象,第一页的图表会呈现超出文本框的景象。Solid:整体排版正确,第一页的图表会呈现超出文本框的景象,第一页的页脚图片透明度辨认谬误。Aspose:整体排版正确,第二页的局部文字下有投影。成果文档 - 论文2.pdf原文档: 各SDK厂商处理结果: ComPDFKit: 在公式局部的转换都是转换了文档中原有的字符,所以会呈现乱码。foxit:并没有辨别小标题的粗体与注释的细体,且局部文本用图片代替,排版相对而言比拟凌乱。Solid: 对公式局部的反对比拟好,然而局部符号应用了形变后的图片代替,比拟影响观感。成果文档 - 图文混排.pdf原文档: 各SDK厂商处理结果:图文混排版面都放弃的不错。 ComPDFkit, foxit, solid 文字的字体和原文档都不太解决,aspose 最靠近, 然而aspose 的背景图片缩放不对。ComPDFkit有几个字最上方被裁掉了。 ComPDFKit: foxit: Solid:Aspose:成果文档 - 图文带简略表格.pdffoxit 的文字背景形态变了,变成了不规则的。aspose 背景图片变小了。ComPDFKit 的工夫有一部分被裁掉了。Solid 成果良好。原文档: ...

August 21, 2023 · 1 min · jiezi

关于pdf:ComPDFKit-专业的PDF文档处理SDK

ComPDFKit提供业余、全平台反对的PDF开发库,包含Windows、Mac、Linux、Android、iOS、Web平台。开发者能够疾速、灵便整合PDF性能到各开发平台的软件、程序、零碎中。丰盛的性能,多种开发语言,灵便的部署计划可供选择,满足您对PDF文档的所有需要。 联系方式:中武官网: https://www.compdf.com/zh-cn 英文官网:https://www.compdf.com/ 领英页面: https://www.linkedin.com/company/pdf-technologies-pte-ltd/ Twitter: https://twitter.com/compdfkit Facebook: https://www.facebook.com/profile.php?id=100085132077341 产品&性能:1.ComPDFKit PDF SDK PDF查看 提供弱小的渲染引擎,轻松渲染简单的PDF文档,反对自定义UI和各种性能操作,如单双页布局,间断滚动,书签,纲要和缩略图等。 PDF批注 领有独立的正文控件。反对增加、删除、编辑、导入、导出、扁平化所有类型的PDF标记以及自定义正文,包含亮高、手绘、文本框、附注等。 PDF签名 反对增加传统的电子签名和数字签名,以跟踪和减速签名工作流程,同时保障签名的真实性和安全性。 PDF表单填写 能够轻松创立、删除、编辑、填写、扁平化和打印表单域,包含文本域、复选框、单选按钮、下拉列表和签名等。 PDF页面治理 增加PDF页面治理性能到应用程序,实现PDF文档减少空白页、删除、复制、重排、旋转、裁剪、拆分合并等页面治理的所有需要。 PDF内容编辑 轻松增加、编辑、删除PDF中的文本和图像,同时反对更改文档内容的大小、字体和色彩等。 PDF平安爱护 通过明码、权限等多种形式对PDF文档进行爱护。针对共享文件,可增加自定义的页眉页脚、水印、贝茨码来爱护知识产权。 标记密文 对图像、文本和矢量图形中的敏感信息或隐衷数据进行不可逆的密文解决,阻止了别人拜访敏感信息。同时反对多种形式标记密文。 PDF转PDF/A 反对PDF文件转换为合乎ISO规范的PDF/A文档,包含PDF/A-1a和PDF/A-1b。为长期、平安地归档电子文件提供解决方案。 PDF文档比照 提供文档比照性能,比照类似的或不同版本的PDF文档。反对比照文档中的文字、图片、线条等内容。以不同色彩展现PDF文档的编辑、删除、减少等变动。 2.ComPDFKit 转档 SDK PDF转Word 反对将PDF文件中的内容转为流排构造的数据,并放弃原文件页面布局。反对字体大小、色彩、粗体、斜体和下划线等辨认。 PDF转Excel PDF文件反对转档有边框、无边框、边框不全的Excel表格,可1:1还原单元格、原文件排版,并反对辨认表格内的公式。 PDF转PPT 提供转档开发库将每页PDF内容转换为可编辑的PPT,将文本转换为文本框;辨认文件内的图片并反对进行旋转、裁剪等操作。 PDF转TXT 反对将PDF转为TXT纯文本格式,简直所有平台都反对关上&浏览的格局,文件体积小便于贮存,关上迅速无缓冲。 PDF转CSV ComPDFKit转档SDK反对从PDF中精确提取表格并将其转换为CSV,一个表格转换为一个CSV文件。 PDF转Image 提供SDK将PDF文件转换为高质量的图像格式,包含PNG和JPEG。保障所有图像品质和分辨率都将放弃不变。 PDF转RTF 提供SDK轻松实现将 PDF 文件转换为可编辑的RTF(富文本格式)文件。 PDF转HTML ComPDFKit转档SDK反对将PDF转为单页或多页的可供网页浏览器读取的HTML网页。 3.ComPDFKit API PDF To / From Word 提供API接口,帮忙您的APP实现PDF文件和Word文件格式互转:PDF转Word、Word转PDF格局。 PDF To / From Excel 提供API接口,帮忙您的APP实现PDF文件和Excel文件格式互转:PDF转Excel、 Excel转PDF格局。 ...

March 7, 2023 · 1 min · jiezi

关于pdf:简单的小技巧如何从网页上下载内嵌的PDF文件

目录前言开始 关上开发者工具选中Network栏目后再抉择XHRCtrl+R(刷新)在新标签页中关上该文件即可获取下载链接开始 关上开发者工具我以谷歌浏览器为例,其余浏览器也是一样操作。下图中就有一个内嵌的《卷积神经网络》PDF文件 选中Network栏目后再抉择XHR此时能够看到XHR中是没有任何货色的。咱们依照其提醒按下Ctrl+R,其实就是刷新一下页面,从新向服务器申请数据。Ctrl+R(刷新)刷新之后,能够看到XHR中多了四个货色,其中最上面就是咱们的指标,PDF文件。在新标签页中关上该文件即可获取下载链接功败垂成

December 28, 2022 · 1 min · jiezi

关于pdf:使用dompdfdompdf实现生成pdf文件

一:dompdf/dompdf地址github:https://github.com/dompdf/dompdf packagist:http://packagist.p2hp.com/pac... 二:dompdf/dompdf装置composer require dompdf/dompdf三:dompdf/dompdf简略实例$pdf = new \Dompdf\Dompdf();$content = 'pdf内容';$pdf->loadHtml($content);//设置纸张大小和方向$pdf->setPaper('A4', 'landscape');$options = new Options();//设置应用近程图片填充pdf内容$options->setIsRemoteEnabled(true);$pdf->setOptions($options);//将html转为PDF$pdf->render();//下载生成的pdf文件$pdf->stream('xxx.pdf');//将生成的pdf保留到服务器file_put_contents('xxx.pdf',$pdf->output());//将生成的pdf文件渲染到页面$pdf->stream('xxx.pdf', [ 'compress' => 0, 'Attachment' => 0]);四:解决生成的pdf文件中文乱码1:下载字体包装置脚本utilshttps://github.com/dompdf/utils 2:字体包装置脚本解决将下载下来的装置脚本中的load_font.php文件拷贝到我的项目的vender平级目录下,而后将须要的字体包文件ttf也放到load_font.php同一级目录下(例如simsun.ttf) 3:执行字体包装置脚本php load_font.php simsun simsun.ttf4:批改装置字体包中的文件门路(留神:不操作此项再本机上是失常的,放到服务器就会有问题了)找到dompdf\dompdf\lib\fonts\installed-fonts.json文件,这时候咱们就能够看到咱们刚刚装置的字体包 这里咱们能够看到引入的字体包相干门路都是本机门路,咱们能够看到 dompdf\dompdf\lib\fonts门路下存在咱们须要的文件,批改引入门路即可,如: 5:html应用字体包款式即可body { font-family: simsun;}依据如上操作咱们就能够解决中文乱码问题

December 19, 2022 · 1 min · jiezi

关于pdf:最好用pdf编辑软件Acrobat-Pro-DC-pdf编辑软件

pdf编辑软件哪个好用?Acrobat Pro DC是最好用的pdf编辑软件,Acrobat Pro DC 将寰球最佳的PDF解决方案晋升到新的高度,配有直观触控式界面,通过开发弱小的新性能,使用户能在任何中央实现工作。Acrobat Pro DC功能强大,它能对于pdf所需制作的内容都可能进行编辑,通过电脑你能够十分轻松地对照片或者文档进行编辑与批改,大大提供效率,它能够关上所有PDF文档,并能与所有PDF文档进行交互。可查看、搜寻、验证和打印  PDF 文件,还能够对其进行数字签名以及开展合作。简略、明了、便捷。Acrobat Pro DC pdf编辑软件下载acrobat pro dcmac软件特色简直任何货色都能够创立PDF应用Acrobat DC,简直能够将任何货色变成高质量的PDF,在任何屏幕上看起来都很棒。您甚至能够疾速拆散和合并文档。编辑PDF并转换它们您无需应用Acrobat DC从头开始从新创立文档。相同,您能够将PDF导出为office等文件格式,或者从PDF外部编辑文本。简略平安地共享和签订PDF通过Acrobat DC,能够在任何设施上随时随地共享文档,发送以供审阅,并使其签名和返回。您能够应用Acrobat进行更多操作无论何时何地,只有您须要实现工作,就能够自信地应用Acrobat DC中的所有弱小性能。

October 4, 2022 · 1 min · jiezi

关于pdf:Mac上的pdf编辑工具PDF-Expert

PDF Expert是一款疾速、笨重、易用的PDF编辑器。可能轻松在MAC上实现PDF编辑、浏览、批注、编辑文本、增加照片、填写表单、签订合同、合并PDF文档以及加密爱护,只需微微点击几下即可。 编辑图片轻松在PDF文件中增加、替换和调整图片或扭转标记或图表,应用PDF Expert所有都将变的那么容易。增加链接能够在文档中任意局部减少连贯。此外,还能够为图像增加链接。订正隐衷信息PDF Expert 能够永恒删除或红色文本和暗藏隐衷数据在你的PDF文档中。找到你所要批改的一句话、词组、短语、数量疾速删除或暗藏起来,这对机密文件十分有用。编辑目录PDF Expert 能够更简略更轻松地浏览整个文件。快捷键能够帮忙在几秒钟做到这一点。子项目的轮廓是一个很有用的性能补充。编辑PDF文档轻松编辑PDF文本,图像,增加自定义图形,弱小的性能超简略的应用办法疾速编辑您的PDF。

August 16, 2022 · 1 min · jiezi

关于pdf:pdf增强插件Enfocus-PitStop-Pro-2022-for-Mac

Enfocus PitStop Pro 2022 Mac版是目前Acrobat PDF上最弱小的PDF加强插件,次要用于查看、编辑和批量批改PDF文件,是很多Acrobat用户必装的PDF插件之一。pitstop pro中文版能够查看您的PDF文件是否有印刷错误、并主动修复PDF中最常见的谬误、让您无需退出Acrobat即可手动编辑PDF的简直所有内容。 性能介绍 PDF品质管制(Preflight)厌倦了手动查看PDF的每一页是否有谬误?PitStop Pro自动检测PDF文件中简直所有可能的谬误。主动更正PitStop Pro不仅能够检测到谬误,还能够让您本人修复或主动实现。PDF编辑PitStop Pro还可让您手动编辑PDF文件中的简直所有内容,而无需来到Adobe Acrobat。

August 15, 2022 · 1 min · jiezi

关于pdf:Mac版pdf编辑器Acrobat-Pro-DC-2022激活补丁

Acrobat Pro DC 2022是一款十分优良的pdf制作软件,将世界上最优良的PDF解决方案晋升到新高度,其配有直观触控式界面及弱小的新性能,能够将任何纸质文件转换为可编辑的电子文件,用于传输、签订和分享。新工具核心能够更简略迅速的拜访常应用的工具。

August 3, 2022 · 1 min · jiezi

关于pdf:pdf转图片

<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.18</version> </dependency> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>jbig2-imageio</artifactId> <version>3.0.2</version> </dependency> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox-tools</artifactId> <version>2.0.18</version> </dependency>@Test public void pdf2image2() throws IOException { PDDocument pdDocument; FileInputStream fileInputStream = new FileInputStream("d:/test.pdf"); pdDocument = PDDocument.load(fileInputStream); PDFRenderer renderer = new PDFRenderer(pdDocument); // 获取PDF页数 int pages = pdDocument.getNumberOfPages(); for (int i = 0; i < pages; i++) { BufferedImage image = renderer.renderImage(i, 2.5f, ImageType.BINARY, RenderDestination.PRINT); FileOutputStream out = new FileOutputStream("d:\\imageresult" + i + ".png"); // PNG ImageIO.write(image, "png", out); } pdDocument.close(); }应用renderImage会小很多 ...

November 18, 2021 · 2 min · jiezi

关于pdf:SpringBoot集成LibreOfficejodconverter做文件预览office转pdf

简介LibreOffice 是一款凋谢源代码的自在收费全能办公软件,可运行于 Microsoft Windows, GNU/Linux 以及 macOS 等操作系统上。它蕴含了 Writer, Calc, Impress, Draw, Math 以及 Base 等组件,可别离用于文本文档、电子表格、幻灯片演示文稿、绘图文档、数学公式编辑、数据库治理等工作。 LibreOffice 采纳对企业和个人用户均收费的 MPL 2.0 受权协定。您能够自在散发该软件,无需领取受权费用(但您依然能够付费取得经认证的业余反对)。它的源代码齐全公开,任何人都能够参加软件的开发和保护。 jodconverter概述JODConverter是 Java OpenDocument 转换器,可在不同办公格局之间转换文档。它利用Apache OpenOffice或LibreOffice,它们为当今可用的 OpenDocument 和 Microsoft Office 格局提供能够说是最好的收费导入/导出过滤器。 JODConverter主动执行 OpenOffice/LibreOffice 反对的所有转换。反对的转换包含(但不限于。您的 OOo 装置反对的所有转换都由 JODConverter 反对): 文件类型 输出格局 输入格局文本 DOC、DOCX、ODT、OTT、RTF、文本等。 DOC、DOCX、HTML、JPG、ODT、OTT、FODT、PDF、PNG、RTF、TXT 等。电子表格 CSV、ODS、OTS、TSV、XLS、XLSX 等。 CSV、HTML、JPG、ODS、OTS、FODS、PDF、PNG、TSV、XLS、XLSX 等。介绍 ODP、OTP、PPT、PPTX等 GIF、HTML、JPG、ODP、OTP、FODP、PDF、PNG、PPT、PPTX、BMP 等。画画 ODG、OTG 等 GIF、JPG、ODG、OTG、FODG、PDF、PNG、SVG、TIF、VSD、BMP 等。其余 HTML DOC、DOCX、HTML、JPG、ODT、OTT、FODT、PDF、PNG、RTF、TXT 等。JODConverter能够以多种不同的形式应用: 指标1.实现office文档->pdf 入门案例装置libreofficelibreoffice官网下载地址下载能够抉择windows/linux或其余操作系统本节依照windows进行测试 新建springboot我的项目,引入以下依赖。 <!--转换工具--> <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-spring-boot-starter</artifactId> <version>4.4.2</version> </dependency> <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-local</artifactId> <version>4.4.2</version> </dependency> <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-core</artifactId> <version>4.4.2</version> </dependency>配置文件jodconverter: local: enabled: true # libreOffice根目录 officeHome: src/main/resources/office-plugin # 工作执行的超时工夫 taskExecutionTimeout: 86400000 # 工作队列的超时工夫 taskQueueTimeout: 86400000 # 端口(线程) portNumbers: [2001,2002,2003] # 一个过程的超时工夫 processTimeout: 86400000以上配置文件是基于本地的libreoffice服务进行配置,更多配置能够查看主动拆卸类JodConverterLocalProperties ...

November 3, 2021 · 1 min · jiezi

关于pdf:前端如何将HTML-生成PDF并避免中文乱码的解决方法

前端生成PDF 如果是非 UTF-8 字符再生成PDF 的过程中容易乱码,且布局容易错乱,是因为前端很多出现后果都是基于字体来绘制的,而前端又无奈通过浏览器拜访客户机的本地资源,因为权限的管制,所以容易导致字体缺失从而导致乱码,因而任何一个前端工具在生成PDF 时候,如果是非英文字体,须要进行字体配置后,通知生成引擎,当渲染该类元素时能够去找这类字体,从而防止错别字。 字体配置所有ActiveReportsJS组件都基于Web浏览器环境来运行。 桌面报表设计器 是基于 Electron应用Chromium来显示用户界面。Web 在线设计器 和 报表 viewer 组件在用户计算机的浏览器中运行的 Web 应用程序。PDF, Excel 和 HTML 导出生成器 基于浏览器环境来测量并生成报表内容。通常状况下,报表由文本内容组成,浏览器通过应用glyphs来渲染的字体形态。字体资源蕴含将字符编码映射到代表这些字符的字形的信息。因而,浏览器须要拜访字体资源,才可能依照预期显示文本。 ActiveReportsJS 中的所有文本项都具备几种字体属性,包含 字体: 字体ID 如 Arial, Calibri, 或 Times New Roman字体款式: 失常 或 斜体字体粗细: 较细,细体,失常,适中,粗体,较粗这三个属性的独特组合称为“字体”。字体系列通常由多个字体组成,通常由独自的文件示意。例如,以下是Windows 零碎中Arial字体系列文件夹的屏幕截图: 当 ActiveReportsJS 渲染报表时,它将这些字体属性翻译成font-family, font-style、font-style 和 font-weight 和font-weightCSS款式属性,并依附浏览器来解析相干的字体资源,提取所需的字形。浏览器有两种形式来拜访字体资源它们可能装置在浏览器运行的零碎中,也可能是可下载的。 应用可下载的字体资源易于保护;所有浏览器都反对它,并且它保障了在所有环境中文本内容的统一输入。此外,ActiveReportsJS PDF 导出须要注册字体,因为它将其子集嵌入到PDF文档中。因而,确保所有环境中报表输入统一的最佳办法是配置ActiveReportsJS组件以拜访可下载的字体资源。本文提供了实现该指标的分步指南。 首先,决定在报表中应用哪些字体系列。它能够是规范字体,如Arial、Times New Roman或Helvetica。也能够是一种或多种网络字体。咱们在演示网站示例报表中应用 Montserrat 字体。在任何状况下,请确保你领有字体的所有文件。ActiveReportsJS反对以下字体格局。 字体格局 文件扩展名 留神WOFF 1.0 (Web 凋谢字体格局) *.woff WOFF 2.0 (Web 凋谢字体格局) *.woff2 IE11 不反对TrueType *.ttf OpenType .ttf, .otf 配置桌面设计器字体您能够在以下地位找到独立的报表设计器字体配置。 ...

June 10, 2021 · 1 min · jiezi

关于pdf:发明-PDF-的-Adobe-联合创始人查尔斯格什克因病去世享年-81-岁

硅谷最驰名和最受尊敬的人物之一,Adobe 公司的联结创始人查尔斯·格什克博士上周五因病逝世,享年 81 岁。 查尔斯·格什克博士于 1982 年与 Xerox 的共事约翰·沃诺克博士独特创建了 Adobe,并公布了引发出版反动的关键技术产品——Adobe PostScript。随后查尔斯·格什克博士于1986年12月至1994年7月负责Adobe首席运营官,并于1989年4月负责总裁,直至2000年4月退休。 查尔斯·格什克在职业生涯里取得了泛滥荣誉,他于 1999 年被选为计算机协会(ACM)的会员。2002 年,被任命为计算机历史博物馆的院士。2006 年,查尔斯·格什克和 约翰·沃诺克 一起取得了美国电子协会的成就奖章。2008 年,他取得了 IEEE 计算机协会的计算机企业家奖和时任美国总统奥巴马颁发的 2008 年国家技术与翻新奖章。2010 年,他与约翰·沃诺克独特被马可尼学会授予马可尼奖。 Adobe 联结创始人,前首席执行官兼董事会主席约翰·沃诺克得悉音讯时苦楚的示意:「我无奈设想去哪能够找到一个像查尔斯·格什克一样优良且让人喜爱的合作伙伴,所有和查尔斯相识的人,无一不十分思念他。」 查克·格施克的人生经验查尔斯·格什克毕业于泽维尔大学,在那里他取得了古典文学学位和数学硕士学位,之后他攻读卡内基梅隆大学计算机科学业余,并取得了博士学位。 他的职业生涯开始于,负责 Xerox 的 Palo Alto 钻研核心的计算机科学实验室研究员,1980 年,他在该实验室帮助建设了施乐影像迷信实验室并负责经理,职责也变成了在监督和发展计算机科学,图形,图像处理和光学畛域的钻研流动。 1982 年,他和约翰·沃诺克为施乐公司进行了交互式图形钻研,但因为难以将其翻新和研究成果从实验室转移到生产中而感到丧气。 两人决定冒险成立公司一家公司去践行本人的想法,随后 Adobe 成立了 ,很快他们的第一个产品 PostScript 面世,它容许将高度具体的业余文档从集体计算机发送到激光打印机。两年之内,Adobe 的支出就冲破 170 万美元。 1985 年,苹果计算机公司购买了 Adobe 19%的股份,并开始用其 LaserWriter 打印机包装 PostScript,从而帮忙苹果计算机公司成为图形设计的当先计算机。 1986 年,Adobe 与德州仪器单干,将 PostScript 应用程序集成到其激光打印机中。尔后不久,IBM 为其集体计算机授予了 PostScript 许可。 随后 Adobe 在 1986 年进行了 IPO(首次公开募股)。 查尔斯·格什克还帮助公司开发出了划时代的软件产品,给人们创作和沟通的形式带来了反动,其中就包含明天宽泛遍及的 PDF、Arobat、Illustrator、Premiere Pro 和 Photoshop 等。 ...

April 19, 2021 · 1 min · jiezi

关于pdf:如何基于DevExpress实现对PDF等文档预览及操作处理

点击获取工具>>在个别的管理系统模块外面,越来越多的设计到一些罕用文档的上传保留操作,其中如PDF、Word、Excel等文档,有时候是通过分布式的WCF技术实现数据的显示和解决,因而心愿间接预览而不须要下载文件,这样可能给咱们提供很多的不便。在DevExpress外面,提供了相应的控件来显示和解决这些文档,本文次要介绍如何利用DevExpress的控件实现对PDF、Word、Excel文档的预览和操作解决。 一、PDF的预览和操作在较早的DevExpress的控件外面,曾经提供了对应的PDF文档的显示控件,不过因为其对PDF格局反对不是很好,有些文档是Office导出的,也不是很失常浏览,因而很少应用,本文介绍的DevExpress的PDF查看控件是基于14.1的,测试过很多文档,如同都能失常关上,因而也想在零碎中宽泛应用了。 为了演示这些控件的解决,我独自编写了一个例子,用来实现对PDF、Word、Excel等文档的解决。 为了显示PDF文档,咱们须要在界面外面增加一个XtraPdfViewer.PdfViewer的控件,这个次要是用来显示PDF的,它有很多属性办法,用来实现对PDF的解决操作,测试界面设计好如下所示。 对PDF,咱们个别次要是用来关上文件,另存为,或者预览就能够了。相干的操作代码如下所示。 `/// <summary>/// PDF测试显示窗体/// </summary>public partial class PDFViewer : Form{//记录窗体的名称readonly string mainFormText; public PDFViewer(){InitializeComponent(); //记录窗体的名称,并实现文档变动事件的解决,不便显示新的文件名称mainFormText = this.Text;pdfViewer1.DocumentChanged += new DevExpress.XtraPdfViewer.PdfDocumentChangedEventHandler(pdfViewer1_DocumentChanged);} /// <summary>/// PDF文档变动后,实现对新文件名称的显示/// </summary>void pdfViewer1_DocumentChanged(object sender, DevExpress.XtraPdfViewer.PdfDocumentChangedEventArgs e){string fileName = Path.GetFileName(e.DocumentFilePath);if (String.IsNullOrEmpty(fileName)){Text = mainFormText;}else{Text = fileName + " - " + mainFormText;}} /// <summary>/// 关上PDF文件/// </summary>private void btnOpenFile_Click(object sender, EventArgs e){string filePath = FileDialogHelper.OpenPdf();if (!string.IsNullOrEmpty(filePath)){this.pdfViewer1.LoadDocument(filePath);}} /// <summary>/// 另存为PDF文件/// </summary>private void btnSaveAs_Click(object sender, EventArgs e){string dir = System.Environment.CurrentDirectory;string filePath = FileDialogHelper.SavePdf("", dir);if (!string.IsNullOrEmpty(filePath)){try{this.pdfViewer1.SaveDocument(filePath);MessageUtil.ShowTips("保留胜利");}catch (Exception ex){LogTextHelper.Error(ex);MessageUtil.ShowError(ex.Message);}}} ...

February 8, 2021 · 2 min · jiezi

关于nginx:工具pdf在线转换并保存

import requestsimport timeclass PDF2Word(): def __init__(self): self.machineid = 'ccc052ee5200088b92342303c4ea9399' self.token = '' self.guid = '' self.keytag = '' def produceToken(self): url = 'https://app.xunjiepdf.com/api/producetoken' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0', 'Accept': 'application/json, text/javascript, */*; q=0.01', 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest', 'Origin': 'https://app.xunjiepdf.com', 'Connection': 'keep-alive', 'Referer': 'https://app.xunjiepdf.com/pdf2word/',} data = {'machineid':self.machineid} res = requests.post(url,headers=headers,data=data) res_json = res.json() if res_json['code'] == 10000: self.token = res_json['token'] self.guid = res_json['guid'] print('胜利获取token') return True else: return False def uploadPDF(self,filepath): filename = filepath.split('/')[-1] files = {'file': open(filepath,'rb')} url = 'https://app.xunjiepdf.com/api/Upload' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0', 'Accept': '*/*', 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Content-Type': 'application/pdf', 'Origin': 'https://app.xunjiepdf.com', 'Connection': 'keep-alive', 'Referer': 'https://app.xunjiepdf.com/pdf2word/',} params = ( ('tasktype', 'pdf2word'), ('phonenumber', ''), ('loginkey', ''), ('machineid', self.machineid), ('token', self.token), ('limitsize', '2048'), ('pdfname', filename), ('queuekey', self.guid), ('uploadtime', ''), ('filecount', '1'), ('fileindex', '1'), ('pagerange', 'all'), ('picturequality', ''), ('outputfileextension', 'docx'), ('picturerotate', '0,undefined'), ('filesequence', '0,undefined'), ('filepwd', ''), ('iconsize', ''), ('picturetoonepdf', ''), ('isshare', '0'), ('softname', 'pdfonlineconverter'), ('softversion', 'V5.0'), ('validpagescount', '20'), ('limituse', '1'), ('filespwdlist', ''), ('fileCountwater', '1'), ('languagefrom', ''), ('languageto', ''), ('cadverchose', ''), ('pictureforecolor', ''), ('picturebackcolor', ''), ('id', 'WU_FILE_1'), ('name', filename), ('type', 'application/pdf'), ('lastModifiedDate', ''), ('size', ''),) res= requests.post(url,headers=headers,params=params,files=files) res_json = res.json() if res_json['message'] == '上传胜利': self.keytag = res_json['keytag'] print('胜利上传PDF') return True else: return False def progress(self): url = 'https://app.xunjiepdf.com/api/Progress' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0', 'Accept': 'text/plain, */*; q=0.01', 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest', 'Origin': 'https://app.xunjiepdf.com', 'Connection': 'keep-alive', 'Referer': 'https://app.xunjiepdf.com/pdf2word/',} data = { 'tasktag': self.keytag, 'phonenumber': '', 'loginkey': '', 'limituse': '1'} res= requests.post(url,headers=headers,data=data) res_json = res.json() if res_json['message'] == '解决胜利': print('PDF解决实现') return True else: print('PDF解决中') return False def downloadWord(self,output): url = 'https://app.xunjiepdf.com/download/fileid/%s'%self.keytag res = requests.get(url) with open(output,'wb') as f: f.write(res.content) print('PDF下载胜利("%s")'%output) def convertPDF(self,filepath,outpath): filename = filepath.split('/')[-1] filename = filename.split('.')[0]+'.docx' self.produceToken() self.uploadPDF(filepath) while True: res = self.progress() if res == True: break time.sleep(1) self.downloadWord(outpath+filename)应用: ...

January 19, 2021 · 2 min · jiezi

关于pdf:vuepdfjs-canvas-踩坑心得

最近公司做了一个我的项目,次要性能是把印章在PDF上拖拽定位的。 这个性能次要两个点: 块的拖拽即时显示印章内容;PDF回显(因波及多人操作,回显包含之前人所签的最终成果)。应用的pdf.js@2.2.28 读取PDF文件,通过canvas 以图像的模式回显在页面上(因为不是单纯的显示,还有很多交互,最终抉择了这个计划) 开始所有都挺顺利的,拖拽计算坐标,PDF回显封装,印章属性设置。。。 PDF回显电子签章在开发过程中没成想PDF回显深了一个大坑,开始是曾经有印章不能回显,在网上搜寻要改pdf.work.js源码,搜寻上面这个判断,都注掉就行了 // if (data.fieldType === 'Sig') {// data.fieldValue = null;// _this3.setFlags(_util.AnnotationFlag.HIDDEN);// }尽管可能显示印章了,但在翻页时会产生只显示一半色彩的状况,钻研了好几天,更换pdf.js 版本、缩小canvas 配置项都没胜利。忽然在一次测试中发现,要是上来就把所有都渲染进去如同就没问题,随即用了一个比拟low的办法,就是上来就把所有pdf都渲染DOM,但不显示进去(display:none),只有与以后页码雷同的才显示,目前测试还没发现问题。 另,现有几个小问题: 布局时尽量用 padding、box-sizing: content-box;,用margin 有时取坐标数据不好管制;因为找的例子是适配挪动端的,外面有个参数window.devicePixelRatio,这个在mac 下通常为2,因为挪动端用这个计算了宽度,在mac 下应用的时候根底坐标都*2了,PC 无脑改成1;对于 window.devicePixelRatio 能够具体参考:张鑫旭-设施像素比devicePixelRatio简略介绍 附上pdf 的例子外围渲染pdf 的局部也是网上收集的,依据业务再进行了批改;pdfjs-fix-sig 只是把电子签章那块解决了,顺手公布在本人的私服上了,npm 上必定没有,失常引到的名称是 pdfjs-dist <template> <div class="pdf-box" id="pdf-box"> <div class="pdf-page-btn-box"> <y-button @click="handleSub()" :disabled="disabledSub">上一页</y-button> <div class="input-box"> <input class="input-wrap" :title="pdfCurrentPage" v-model="tunePage" @blur="pageChange" @keyup.13="pageChange"/> </div> <div class="num-page-box"> / {{pdf_pages}}</div> <y-button @click="handleAdd()" :disabled="disabledAdd">下一页</y-button> </div> <div class="pdf-view-wrap"> <div ref="canvasBox" class="canvas-box" id="canvas-box" :style="{width:`${pdf_div_width}px`,margin:'0 auto'}"> <slot name="drag-collection-box"></slot> <!-- <canvas ref="canvasPage" :id="'the-canvas'+pdfCurrentPage"--> <!-- style="border: 1px #eeeeee solid;"></canvas>--> <template v-for="index in pdf_pages"> <canvas ref="canvasPage" :id="'the-canvas'+index" v-show="index === Number(pdfCurrentPage)" style="border: 1px #eeeeee solid;"></canvas> </template> </div> </div> <ul v-if="sealPlaceShow" class="seal-place" ref="sealPlace" :style="`height: ${canvasHeight}px`"> <li v-for="index in 5"></li> </ul> </div></template><script> // 筹备PDF文件和签章数量、类型 import Vue from "vue"; let PDFJS = require('pdfjs-fix-sig'); PDFJS.GlobalWorkerOptions.workerSrc = Vue.prototype.GLOBAL.dataUrl + '/staticFront/script/pdfjs-fix-sig/build/pdf.worker.min.js'; export default { name: "pdf-box", props: { pdfSrc: { type: String }, sealPlaceShow: { type: Boolean, default: false } }, data() { return { pdf_scale: 1,//pdf放大系数 (1.33 回显的pdf 章是100,但思考到回显的pdf是按595*841展现【所对应应的章是75*75】),A4: 595 * 841 pdf_pages: null, pdfDoc: null, pdf_div_width: '595', pdf_src: null, pdfCurrentPage: 1, tunePage: 1, disabledAdd: false, disabledSub: true, // 初始不能减页 canvasWidth: 0, canvasHeight: 0, sealPlaceFlag: false, } }, watch: { sealPlaceShow: { handler(val) { this.sealPlaceFlag = val; }, immediate: true } }, created() { if (this.pdfSrc.length > 0) { this.getPdfUrl(); } else { this.$Message.error({content: '请应用正确的PDF文件'}); } }, methods: { getPdfUrl() { //取得pdf //例子:加载pdf文件示例; this.loadFile(this.pdfSrc); //线上申请 文件流(2020年11月03日 08:55:02 未测试) // this.$http.get(this.pdfSrc).then((res) => { // this.pdf_src = res.url; // this.loadFile(this.pdf_src) // }, (err) => { // console.log(err); // }); }, //初始化pdf loadFile(url) { let _this = this; let loadingTask = PDFJS.getDocument(url); loadingTask.promise.then((pdf) => { _this.pdfDoc = pdf; _this.pdf_pages = _this.pdfDoc.numPages; // 总页数 _this.$nextTick(() => { _this.setAddSubBtn(); for (let i = 1; i <= _this.pdf_pages; i++) { _this.renderPage(i) } }) }) }, //渲染pdf页 renderPage(num) { let _this = this; this.pdfDoc.getPage(num) .then((page) => { let canvas = document.getElementById('the-canvas' + num); let ctx = canvas.getContext('2d'); // let dpr = window.devicePixelRatio || 1; // mac 的 window.devicePixelRatio 为 2 let dpr = 1; let bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; let ratio = dpr / bsr; let viewport = page.getViewport({scale: this.pdf_scale}); canvas.width = viewport.width * ratio; canvas.height = viewport.height * ratio; _this.canvasWidth = canvas.width; _this.canvasHeight = canvas.height; _this.$emit('setCanvasAttr', { canvasWidth: _this.canvasWidth, canvasHeight: _this.canvasHeight, pdfCurrentPage: _this.pdfCurrentPage, numPages: this.pdfDoc.numPages }); canvas.style.width = viewport.width + 'px'; _this.pdf_div_width = viewport.width; // 定位在左边时须要canvas的宽度进行计算 canvas.style.height = viewport.height + 'px'; ctx.setTransform(ratio, 0, 0, ratio, 0, 0); let renderContext = { canvasContext: ctx, viewport: viewport }; page.render(renderContext).promise.then((res) => { // console.log(this.getBounding('canvasPage')); // console.log(this.getEleClass('layout-menu-left').clientWidth); // console.log(this.getBounding('canvasPage').right - this.getEleClass('layout-menu-left').clientWidth + 'px'); }); }); }, // 减页 handleSub() { this.pdfCurrentPage--; this.tunePage = this.pdfCurrentPage; this.setAddSubBtn(); }, // 加页 handleAdd(_str) { this.pdfCurrentPage++; this.tunePage = this.pdfCurrentPage; this.setAddSubBtn(); }, // 判断翻页按钮是否禁用并渲染canvas setAddSubBtn() { this.disabledSub = this.pdfCurrentPage <= 1; this.disabledAdd = this.pdfCurrentPage >= this.pdf_pages; // this.renderPage(this.pdfCurrentPage); this.$emit('setCanvasAttr', { canvasWidth: this.canvasWidth, canvasHeight: this.canvasHeight, pdfCurrentPage: this.pdfCurrentPage, numPages: this.pdfDoc.numPages }); }, pdfChangePage() { this.$emit('pdf-change-page', true); }, getEleClass(_str) { return document.getElementsByClassName(_str)[0]; }, getBounding(_str) { return this.$refs[_str].getBoundingClientRect(); }, pageChange() { // 输出字符容错 this.pdfCurrentPage = isNaN(Number(this.tunePage)) ? 1 : Number(this.tunePage); // 输出大数容错 this.pdfCurrentPage = this.tunePage > this.pdf_pages ? this.pdf_pages : this.tunePage; this.setAddSubBtn(); } } }</script>父级援用<pdfBox ref="pdfBox" :pdfSrc="doSignData.originFile" :canvasHeight="canvasHeight" :sealPlaceShow="true"> <div slot="drag-collection-box" v-if="$route.meta.viewType !== 'view'"> <!-- 这个插槽放在pdf 上显示的印章 --> </div> </pdfBox>最初放上款式@drag-block-size: 75px;.e-sign-wrap { .pdf-page-btn-box { position: absolute; text-align: right; font-size: 12px; right: 0; z-index: 5; padding: 7px; color: #42474f; .input-box, .num-page-box { display: inline-block; height: 22px; line-height: 22px; } .input-box { width: 30px; .input-wrap { width: 100%; padding: 0 2px; font-size: 12px; border: 1px transparent solid; border-bottom: 1px #dddee1 solid; border-radius: 2px; color: #495060; text-align: right; &:focus { outline: none; } } } .num-page-box { vertical-align: middle; } } .pdf-box { float: left; font-size: 0; position: relative; .pdf-view-wrap { position: relative; display: inline-block; .drag-box { li { cursor: move; user-select: none; position: absolute; opacity: .7; z-index: 5; border: 1px dashed transparent; .party { color: #ffffff; height: 24px; line-height: 24px; padding-left: 5px; width: 100%; font-size: 12px; } .content { width: 98px; height: 49px; line-height: 18px; padding: 5px; font-size: 14px; text-align: center; display: table-cell; vertical-align: middle; word-break: break-all; .sign-type { font-size: 12px; } } &.drag-block { width: @drag-block-size; height: @drag-block-size; background-color: #cfddfb; .party { background-color: #9bbcff; } .content { color: #78a5ff; } } &.place-block { width: @drag-block-size; height: @drag-block-size; background-color: #ffcccc; .party { background-color: #f09494; } .content { color: #f09494; line-height: 16px; padding: 0; font-size: 12px; } //.btn-box { // .btn { // width: 100%; // } //} } &.drag-block, &.place-block { &.checked::after { content: ''; width: 100%; height: 100%; border: 2px #004CC0 solid; display: block; position: absolute; top: 0; left: 0; z-index: 0; } img { -webkit-user-drag: none; } } .btn-box { cursor: pointer; .btn { //float: left; width: 100%; font-size: 12px; text-align: center; height: 24px; line-height: 24px; background-color: #004cc0; color: #ffffff; } } } } canvas { width: 595px; height: 842px; //max-width: 595px; //max-height: 841px; } } .seal-place { display: inline-block; position: absolute; right: -25px; min-height: 841px; li { width: 5px; height: 100%; display: inline-block; border: 1px #eee solid; border-left: none; } } }}

January 15, 2021 · 4 min · jiezi

关于pdf:pdfjsdist模块实现pdf文件预览功能

对于pdf文件,通过测试ios是能够失常关上,而在安卓机上,则须要下载福昕阅读器能力关上。如何可能不借助客户端之力,依附h5来实现pdf文件预览性能呢?咱们能够装置pdfjs-dist模块来实现。本示例是基于vue框架: 装置pdfjs-dist包:npm install pdfjs-dist -D 这里应用的版本是:"pdfjs-dist": "^2.4.456" 2、html模板 <template> <div class="canvas-container"> <canvas v-for="page in pages" :id="'the- canvas'+page" :key="page"> </canvas> </div></template>3、script代码段 import PDFJS from 'pdfjs-dist';import workerSrc from 'pdfjs-dist/build/pdf.worker.entry'PDFJS.workerSrc = workerSrc;export default { name: 'Pdf', data() { return { pages: [] }; }, created() { this._loadFile(yourUrl); }, methods: { _renderPage (num) { this.pdfDoc.getPage(num).then((page) => { let canvas = document.getElementById('the-canvas' + num) var vp = page.getViewport({scale: 1}); let ctx = canvas.getContext('2d') let dpr = window.devicePixelRatio || 1 let bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1 let ratio = dpr / bsr let viewport = page.getViewport({scale: window.innerWidth / vp.width}); canvas.width = viewport.width * ratio canvas.height = viewport.height * ratio canvas.style.width = viewport.width + 'px' ctx.setTransform(ratio, 0, 0, ratio, 0, 0) let renderContext = { canvasContext: ctx, viewport: viewport } page.render(renderContext) if (this.pages > num) { this._renderPage(num + 1) } }) }, _loadFile (url) { this.$showLoading(); PDFJS.getDocument(url).promise.then((pdf) => { this.$closeLoading(); this.pdfDoc = pdf this.pages = this.pdfDoc.numPages this.$nextTick(() => { this._renderPage(1); }); }); } }};4、css代码 ...

August 28, 2020 · 1 min · jiezi

关于pdf:Pdf-转换-图片

PDDocument document = null; String pdfdir = "d:/pdf2image/"; File file = new File(pdfdir); if(!file.exists()||!file.isDirectory()){ System.out.println("the diretory is not exist"); return; } File [] files = file.listFiles(); for(File pdf :files){ String filepath = pdf.getAbsolutePath(); if(!filepath.contains(".pdf")){ continue; } String filename = pdf.getName(); String imageNamePrefix = filename.substring(0,filename.lastIndexOf(".")); File imagedir = new File(pdfdir+imageNamePrefix); if(!imagedir.exists()){ imagedir.mkdir(); } InputStream inputStream = new FileInputStream(pdf); document = PDDocument.load(inputStream); PDFRenderer renderer = new PDFRenderer(document); int pageCount = document.getNumberOfPages(); System.out.println("共 "+pageCount+" 页."); for (int i = 0; i < pageCount; i++) { BufferedImage image = renderer.renderImage(i, 1.9f); ImageIO.write(image, "jpg", new File(pdfdir+imageNamePrefix+File.separator+ i + ".jpg")); } }<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.18</version> </dependency>

July 29, 2020 · 1 min · jiezi

怎么将PDF转换成Word手机上PDF转成Word最便捷的方法

怎么将PDF转换成Word?在工作过程中我们总会遇到各种有关文件格式转换的问题,比如PDF转换成Word、PDF转换成Excel、Word转换成Excel等。今天小编将要分享给大家一个好方法,帮助大家快速解决文件格式转换问题。 1:在手机应用市场找到并打开我们的转换工具迅捷PDF转换器,打开后在首页选择并点击PDF转换Word按钮,进入准备阶段。 2:进入文件添加页面,找到并点击准备好的文件,进入PDF文件转换页面。 3:在PDF转换成Word页面,点击确认转换按钮即可开始进行文件转换。 4:转换成功后,文件会自动保存在文件库中,点击预览按钮,可以查看文件转换效果,点击分享按钮,可以分享文件。 5:点击进入文件库,在文件库中你可以对文件进行各种编辑,比如重命名、分享等等,满足自己的需要。 6:图片识别文字功能,在转换器中还有许多实用性很强小功能,比如PDF压缩功能、图片识别文字功能等等,满足你的需要。 以上就是小编分享的PDF转换成Word文件格式最便捷的方法,小伙伴们看到后是不是觉得小编的方法特别简单呢?如果你刚好需要的话,不妨赶紧尝试一下,小编的方法也同样可以套用到其他文件格式的转换中。

October 17, 2019 · 1 min · jiezi

PDF文件转CAD图纸中怎么设置文件保存位置

在设计行业中使用图纸是比较多的,日常工作中就会遇到一些PDF格式的图纸文件,但是PDF文件就会有一个问题,就是不能够进行编辑。那为了工作的需要就要将PDF文件转换为CAD图纸。下面就来给大家具体演示一下PDF转CAD中设置文件保存位置的方法。 步骤一:先在电脑中安装好需要使用的CAD软件,可以在百度浏览器中输入【迅捷CAD转换器】进入到下载安装界面中,然后根据操作步骤将CAD软件安装到桌面上并将其进行启动进入到操作界面中。步骤二:我们进入到CAD转换器的操作界面中,选择左侧功能栏中的【PDF转CAD】选项,点击界面上方中的【添加文件】属性按钮,在界面弹出的【打开】对话框中找到需要转换的PDF文件进行打开。步骤三:CAD文件添加完成后,选择右上方的【浏览】按钮,然后界面会跳转到【选择文件夹】中,点击桌面后选择一个文件夹作为文件转换后保存的位置。步骤四:在图纸转换前,在软件左下方中的【输出类型】中,有两种文件转换格式为DWG以及DXF。根据转换文件的需要来进行选择。步骤五:然后,我们就可以点击右下角的【批量转换】按钮将PDF文件转换为CAD图纸了,转换后的文件就可以在干设置的文件夹中查找。好了,以上就是给大家分享的PDF文件转CAD图纸中怎么设置文件保存位置的具体操作方法,根据以上操作方法就可以进行转换,掌握好以上图纸格式转换的方法,就可以轻松解决其它CAD图纸格式转换的问题。如需了解其它CAD教程的使用方法,就可以前往迅捷CAD【软件帮助】中查找,希望能够帮助到大家。

October 16, 2019 · 1 min · jiezi

如何利用PDF格式转换器在手机上完成PDF格式转换

如何利用PDF格式转换器在手机上完成PDF格式转换?在我们处理工作文件的过程中,经常会遇到一个问题就是文件格式的处理,比如PDF转换Word、PDF转换Excel等。所以今天小编要为大家带来一个PDF文件格式转换的方法,希望可以帮助到大家。1:在手机应用市场找到并打开我们的转换工具迅捷PDF转换器,打开后在首页选择自己想要的文件格式转换方式,比如PDF转换Word。2:进入文件添加页面,点击事先准备好的文件,进入PDF文件转换页面。3:在文件转换页面,点击确认转换即可开始进行文件转换。4:转换成功后,文件会自动保存在文件库中,点击预览按钮,可以查看文件转换效果,点击分享按钮,可以分享文件。5:点击进入文件库,在文件库中你可以对文件进行各种编辑,比如重命名、分享、删除等等,满足自己的需要。6:在PDF格式转换器中,还有小功能应用,比如拍照翻译,点击拍照翻译便可以进行英汉互译翻译。以上就是小编分享的利用PDF格式转换器在手机上完成PDF格式转换的方法,是不是非常简单。让你出差不必带着沉重的电脑,也能快速解决文件格式转换问题,轻松处理文件。

October 14, 2019 · 1 min · jiezi

The-correct-way-to-edit-PDF-metadata-in-Python

The correct way to edit PDF metadata in PythonThere are several ways to edit PDF metadata in Python, but one way is better than the others. I will start by talking about other ways that seem right but have side effects. Skip to the end of this article if you don’t have enough time and just use the correct way. Weakness is package not maintained. from pdfrw import PdfReader, PdfWriter, PdfDictif __name__ == '__main__': pdf_reader = PdfReader('old.pdf') metadata = PdfDict(Author='Someone', Title='PDF in Python') pdf_reader.Info.update(metadata) PdfWriter().write('new.pdf', pdf_reader)pdfrw can do quite easily without losing non-display information such as bookmarks.PyPDF2 supports more PDF features than pdfrw, including decryption and more types of decompression. ...

October 4, 2019 · 2 min · jiezi

开发函数计算的正确姿势借助-Ghostscript-将-PDF-转换成-JPG-精简版-0-0-0

前言首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考。Fun:Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它通过一个资源配置文件(template.yml),协助您进行开发、构建、部署操作。Fun 的更多文档参考。Ghostscript:Ghostscript 是一套建基于Adobe、PostScript及可移植文档格式(PDF)的页面描述语言等而编译成的自由软件。参见维基百科词条备注: 本文介绍的技巧需要 Fun 版本大于等于 3.0.0-beta.7 。 依赖工具本项目是在 MacOS 下开发的,涉及到的工具是平台无关的,对于 Linux 和 Windows 桌面系统应该也同样适用。在开始本例之前请确保如下工具已经正确的安装,更新到最新版本,并进行正确的配置。 DockerFunFun 工具依赖于 docker 来模拟本地环境。 对于 MacOS 用户可以使用 homebrew 进行安装: brew cask install dockerbrew tap vangie/formulabrew install funWindows 和 Linux 用户安装请参考: https://github.com/aliyun/fun/blob/master/docs/usage/installation.md安装好后,记得先执行 fun config 初始化一下配置。 注意, 如果你已经安装过了 fun,确保 fun 的版本在 3.0.0-beta.7 以上。 $ fun --version3.0.0-beta.7初始化使用 fun init 命令可以快捷地将本模板项目初始化到本地。 fun init vangie/ghostscript-example安装依赖$ fun installInstalling recursively on fun.ymlskip pulling image aliyunfc/runtime-python3.6:build-1.6.1...Task => workaround for update-gsfontmap => bash -c 'mkdir -p /code/.fun/root/etc/ghostscript/cidfmap.d/ && mkdir -p /code/.fun/root/etc/ghostscript/fontmap.d/ && mkdir -p /etc/ghostscript/ && mkdir -p /var/lib/ghostscript/ && mkdir -p /code/.fun/root/var/lib/ghostscript/fonts && ln -s /code/.fun/root/etc/ghostscript/cidfmap.d /etc/ghostscript/ && ln -s /code/.fun/root/etc/ghostscript/fontmap.d /etc/ghostscript/ && ln -s /code/.fun/root/var/lib/ghostscript/fonts /var/lib/ghostscript/'Task => [UNNAMED] => apt-get update (if need) => apt-get install -y -d -o=dir::cache=/code/.fun/tmp/install ghostscript --reinstall => bash -c for f in $(ls /code/.fun/tmp/install/archives/*.deb); do dpkg -x $f /code/.fun/root; mkdir -p /code/.fun/tmp/install/deb-control/${f%.*}; dpkg -e $f /code/.fun/tmp/install/deb-control/${f%.*}; if [ -f "/code/.fun/tmp/install/deb-control/${f%.*}/postinst" ]; then FUN_INSTALL_LOCAL=true /code/.fun/tmp/install/deb-control/${f%.*}/postinst configure; fi; done;Creating config file /etc/papersize with new version => bash -c 'rm -rf /code/.fun/tmp/install/archives'本地调用$ fun local invoke pdf2jpgusing template: template.ymlskip pulling image aliyunfc/runtime-nodejs10:1.6.1...FC Invoke Start RequestId: 21d9c646-1db4-403c-b018-cd4246e193d3load code for handler:index.handler2019-09-18T09:45:38.400Z 21d9c646-1db4-403c-b018-cd4246e193d3 [verbose] stdout =================== START2019-09-18T09:45:38.400Z 21d9c646-1db4-403c-b018-cd4246e193d3 [verbose] GPL Ghostscript 9.26 (2018-11-20)Copyright (C) 2018 Artifex Software, Inc. All rights reserved.This software comes with NO WARRANTY: see the file PUBLIC for details.Processing pages 1 through 1.Page 12019-09-18T09:45:38.401Z 21d9c646-1db4-403c-b018-cd4246e193d3 [verbose] stdout =================== ENDFC Invoke End RequestId: 21d9c646-1db4-403c-b018-cd4246e193d3convert success.JPG file save to /tmp/test.jpg2019-09-18T09:45:38.416Z 21d9c646-1db4-403c-b018-cd4246e193d3 [error](node:21) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.RequestId: 21d9c646-1db4-403c-b018-cd4246e193d3 Billed Duration: 2132 ms Memory Size: 1998 MB Max Memory Used: 78 MB可以查看文件 .fun/tmp/invoke/ghostscript/pdf2jpg/test.jpg ,预留转换后的效果。 ...

September 20, 2019 · 2 min · jiezi

markdown免费转换为pdf

安利一个markdown免费转换为pdf的开源网站, 很好用,关键还免费使用很简单,一键导出, 支持的语法格式比较多,可以添加水印,页眉markdown转pdf网站

July 11, 2019 · 1 min · jiezi

php下载PDF文件

前言项目近期有个业务需求:下载PDF版发票。和公司前辈沟通,有两种方案 先做成图片,把动态数据用画布坐标的形式填充进去,把图片放进PDF文件中,再下载(比较繁琐)先用html画页面,再转成PDF文件,再下载(觉得用这种方式)一、安装依赖wkhtmltopdf依赖安装(https://wkhtmltopdf.org/downloads.html)可以直接在官网下载安装包,像服务器通过通过以下方式(找好对应的版本下载呦,我用的是ubantu 16)wget https://downloads.wkhtmltopdf.org/0.12/0.12.5/wkhtmltox_0.12.5-1.xenial_amd64.debapt-get install -f dpkg -i wkhtmltox_0.12.5-1.xenial_amd64.deb如果出现以下错误,就重复下上面第二行命令和第三行命令 dpkg: error processing package wkhtmltox (--install): dependency problems - leaving unconfiguredErrors were encountered while processing: wkhtmltox二、代码演示 $outPut = view('invoice', [ 'orderData' => $orderData ])->render(); //invoice.blade.php是html模板,往里填充动态数据 //将填充完整的html文件存储起来,稍后用来转PDF $htmlName = $this->getHtmlName();//获取html文件名 $htmlDir = $this->getHtmlDir();//获取 html 工作目录 $htmlFullPath = storage_path($htmlDir . $htmlName); file_put_contents($htmlFullPath, $outPut); //设置pdf文件路径 $pdfName = $this->getPdfName($orderData['order_no']);//获取pdf文件名 $pdfDir = $this->getPDFDir();//获取 pdf 工作目录 $pdfFullPath = storage_path($pdfDir . $pdfName); //设置PDF文件的属性 $pdf = new Pdf($htmlFullPath); $pdf->setOptions([ 'no-outline', //'zoom' => 3, 'margin-top' => 0, 'margin-right' => 0, 'margin-bottom' => 0, 'margin-left' => 0, //'disable-smart-shrinking', ]); //保存PDF if (!$pdf->saveAs($pdfFullPath)) { \Log::error('Could not create PDF:', [$pdf->getError()]); return false; }因为我们项目使用了多台服务器,所以我们就把PDF文件先上传到oss再进行下载的,如果不需要可以直接用Header方式下载 ...

June 17, 2019 · 1 min · jiezi

基于前端技术生成PDF方案

需求背景业务系统需要预览报告(如产品周报,体检报告等)并生成pdf格式供用户下载,或者定期发送给指定用户报告格式相对固定,由文本,图片和图表组成,基本与前端页面保持一致解决方案需求分为两步:报告预览和报告生成。 报告预览在前端进行展示,可使用前端技术,如React/Vue等技术栈对其进行还原,数据从服务端获取。报告生成需要对第一步生成的HTML进行PDF的转换生成,HTML2PDF的方式又分为两种: 基于canvas的客户端生成方案基于nodejs + puppeteer的服务端生成方案一个完整的案例下面以一个体检报告的案例进行这两种方案的说明:体检报告展示形式如下,格式相对固定,分为四个页面:个人信息页,建议页,原理页,个人信息页与建议页数据来源于服务器。report.png 基于canvas的客户端生成方案canvas是HTML5标准中新增的元素,可用于通过使用JS的脚本来绘制图形。canvas提供了toDataURL/toBlob方法,用于把canvas中的内容转换为图片,API文档如下(来源于MDN): 由于HTML文档再浏览器中是以DOM树的形式存在,所以我们可以通过三步完成HTML到PDF的转换: 将DOM树转换为canvas对象,可使用html2canvas完成将canvas转换为图片,可使用canvas.toDataURL完成将图片转换为PDF,可使用jsPDF完成完整代码实现:https://github.com/simonwoo/d... 截图如下,点击下载按钮可进行pdf生产: 该方案完全基于客户端的方式生成,不需要服务器进行支持。在使用该方案的过程中,发现了一些问题: 生产的PDF比较模糊,质量不高如果HTML中有外链图片,无法生成由于第一步是通过DOM去生成canvas,所以针对特别长的报告,DOM尚未加载完便点击下载时,会造成报告生成问题因为是客户端方案,所以需要用户主动触发生成,但对于一些定期发送给用户的报告,该方案无法使用基于nodejs + puppeteer的服务端生成方案puppeteer是google推出的headless浏览器,即没有图形界面的浏览器,但又可以实现普通浏览器HTML/JS/CSS的渲染,以及其他基本浏览器功能。你可以理解为一个没有界面的Chrome浏览器。主要有以下几种使用场景: 生成页面的截图和PDF抓取SPA并生成预先呈现的内容(即“SSR”)爬虫,从网站抓取你需要的内容自动化测试,自动表单提交,UI测试,键盘输入等创建一个最新的自动化测试环境。使用最新的JavaScript和浏览器功能,直接在最新版本的Chrome中运行测试通过理解puppeteer的功能,我们可以开启一个实例去渲染HTML报告,然后再利用其提供的转换PDF功能进行PDF的生成。 两个重要的API: page.goto(url, [options]) - 打开指定url的文件,可以是本地文件(file://)也可以是网络文件(http://)page.pdf([options]) - 转换页面成PDF文件puppeteer使用一个小例子,将百度网页转换为pdf: 完整代码如下: 前端部分:https://github.com/simonwoo/d...后端部分:https://github.com/simonwoo/d...项目启动流程如下: 进入到webapp目录,使用npm install和npm run start启动前端服务器,地址为:localhost:3000进入到server目录,使用npm install和npm run dev启动node服务器,地址为:localhost:7001整个服务架构如下: node服务器通过路由增加一个pdf生成的controller,该controller通过启动puppeteer实例去加载localhost:3000的页面并生成pdf。直接在浏览器中通过http://localhost:7001/pdf即可访问到生成的pdf. 在实际环境中,前端页面可部署在nginx服务器上或者直接放在Node服务器上,puppeteer也支持使用cookie的操作,这样可以避免一些需要身份认证的问题。 相比客户端生成方式,使用puppeteer生成的pdf质量比较高,可满足生产要求。 本文中提到的两种方案中,均省去了ajax后端请求数据部分,读者可根据需要自行增加。 Referencehtml2canvas - https://html2canvas.hertzen.c...jsPDF - https://github.com/MrRio/jsPDFpuppeteer - https://zhaoqize.github.io/pu...Eggjs - https://eggjs.org/zh-cn/原文链接:https://juejin.im/post/5d036a...

June 15, 2019 · 1 min · jiezi

学习心得系列之论一个小开源项目的推广

将近一个月没有更新博客了, 一方面, 临近期末, 临时报个佛脚, 应该也是有点用的吧????; 另一方面, 最近在忙活自己的开源项目宣传工作, 项目地址详见: Github, 进而有了写这篇文章的想法, 旨在记录自己的宣传之道(PS: 不是传销...). 前言一个在校生, 就不要想着为社区做多大贡献了 ——知乎现在觉得, 那位大佬说的还是挺有道理的, 一个初生的牛犊, 修为尚浅, 的确不能为开源社区做多大的贡献. 但是这不行啊, 爱折腾的我们, 怎么能闲着? 下面的所有一切一切, 都将围绕我的开源仓库——fe-necessary-book, 一一展开. 项目选型对于一个开源项目来说, 项目的选型是格外重要的, 在我看来, 有以下几个方面: 我开源这个项目的动机?该项目是做什么的?对于个人来说: 一个简单的、易用的demo一个小应用程序一份文档工具集合都可以作为我们开源的对象, 也许你的一个小项目, 会帮助到比你晚入门的小小白, 收获star获得兴奋感的同时, 又帮助了他人, 何乐而不为? 前期工作俗话说: 工欲善其事,必先利其器既然我们选择了这件事, 就该专心的做好它. 开源应是如此, 在项目初期, 可以搜寻一些与你开源主题相关的资料, 以及前人的经验. 这两步是非常重要的, 阅读他人的优秀仓库, 可以给你指明方向. 然后你可以在此基础上加上你自己的想法, 就拿我来说, 我建立本仓库的目的是为了: 分享健康有关的书籍分享有关前端的优质书籍分享有趣的前端开发工具分享大厂前端团队博客当然, 我觉得最有用的当属——码农长寿指南区块了. 后期推广一个优秀的项目, 即使你代码写的再好, 没有合适的推广, 别人又怎会知道?做好了项目的前期准备工作, 最重要的一步来了, 那就是大力宣传, 注意, 这可不是传销, 但是你要当它是传销. ...

June 7, 2019 · 1 min · jiezi

HTML-转-PDF-图文报表实践

导出 PDF 图文报表实践 方法一: jsPDF使用 jsPDF 时,需要注意的是其默认单位为 mm,需要在 new jsPDF() 时传入配置 const doc = new jsPDF({ unit: 'px', format: 'a4'})这个方法废了。这个鬼东西多行文本和多个图片,简直要人命! 方法二: wkhtmltopdf Vue SSR使用 Vue.js ,需要 SSR 支持,否则页面为空白 使用 Nuxt.js 作为服务端渲染框架,这里记录一下遇到的问题和解决方案 1. 使用 Element UI,启动就报错 HTMLElement is not definedElement UI 版本问题,使用最新的 2.8.x 会出现问题,则需要降版本并在 package.json 中配置版本策略,仅更新小版本范围 "element-ui": "~2.4.11",参考资料:https://github.com/ElemeFE/element/issues/15261 2. JS的兼容问题在使用 wkhtmltopdf 时,提示报错:Warning: http://localhost:3000/_nuxt/vendors.app.js:1941 SyntaxError: Parse error,估计是 ES6 的语法在wkhtmltopdf 的运行环境当中不支持,导致出现了这些错误提示。 官方Nuxt.js 2.6.X 版本其实给了 babel 的配置,默认会自动根据浏览器的运行环境做代码兼容,并不需要以下的这些设置(下面只是自己的实践过程,供参考),请直接使用第3点的解决方法。 ...

May 22, 2019 · 2 min · jiezi

基于HTML5转换PDF的电子书阅读插件

基于HTML5转换PDF的电子书阅读插件html5部分项目一般都是以pdf.js插件阅读PDF文件,但存在阅读体验不理想的情况,所以参考手机上的电子书阅读器,使用国外的链接描述http://fliphtml5.com制作电子书示例。 完整代码已上传git,标题搜索即可。 插件功能强大,缩略图,鼠标翻页,放大缩小都可以,部分配置代码config.js如下 var bookConfig = { appName:'flippdf', totalPageCount : 0, largePageWidth : 1080, largePageHeight : 1440, normalPath : "files/page/", largePath : "files/large/", thumbPath : "files/thumb/", ToolBarsSettings:"", TitleBar:"", appLogoLinkURL:"", bookTitle:"FLIPBUILDER", bookDescription:"", ButtonsBar:"", ShareButton:"", ThumbnailsButton:"", ThumbnailsButtonVisible:"Hide", ZoomButton:"", ZoomButtonVisible:"No", FlashDisplaySettings:"", MainBgConfig:"", bgBeginColor:"#cccccc", bgEndColor:"#eeeeee", bgMRotation:45, pageBackgroundColor:"#FFFFFF", flipshortcutbutton:"Hide", BookMargins:"", topMargin:10, bottomMargin:10, leftMargin:10, rightMargin:10, HTMLControlSettings:"", linkconfig:"", LinkDownColor:"#808080", LinkAlpha:0.5, OpenWindow:"_Blank", BookMarkButtonVisible:'False', productName : 'Demo created by Flip PDF', homePage : 'http://www.html5.com/', isFlipPdf : "False", TableOfContentButtonVisible:"False", searchTextJS:'javascript/search_config.js', searchPositionJS:undefined};java部分maven引入 ...

May 22, 2019 · 2 min · jiezi

解决 SmallPDF 联网验证和试用期过期问题

特别感谢:攻防之间SmallPDF 是一款非常好用的 PDF 工具箱,具有压缩、格式转换、合并分割、解锁、保护等实用功能。它的在线版是完全免费的,但是文件传输很慢,桌面版完全在本地执行操作,免费试用 5 次。首先确认一下版本,我的版本是 1.24.0,不保证这个方法以后还能用。<!– more –>解决联网验证SmallPDF 安装之后需要联网验证,否则一直卡在这个界面。SmallPDF 在配置文件C:\Users{user}\AppData\Roaming\Smallpdf\preferences.json中储存配置,其中{user}是你的计算机用户名。如果你碰到了这种情况,打开配置文件,找到这一行,我这里大概是 13 行: “system.local_token”: null,把值改成"1",然后给这个文件设为只读。解决试用期过期打开配置文件,找到这一行,我这里大概是 44 行: “system.trial_duration_limit”: 5,把它改成 999999999999,然后给这个文件设为只读。再打开应用程序,就发现可以用了:

April 17, 2019 · 1 min · jiezi

前端实现在线预览pdf、word、xls、ppt等文件

1、前端实现pdf文件在线预览功能方式一: 通过a标签href属性实现pdf文件理论上可以在浏览器直接打开预览但是需要打开新页面。在仅仅是预览pdf文件且UI要求不高的情况下可以直接通过a标签href属性实现预览<a href=“文档地址”></a>方式二: 通过jquery插件jquery.media.js实现这个插件可以实现pdf预览功能(包括其他各种媒体文件)但是对word等类型的文件无能为力。实现方式: <script type=“text/javascript” src=“jquery-1.7.1.min.js”></script> <script type=“text/javascript” src=“jquery.media.js”></script>html结构: <body> <div id=“handout_wrap_inner”></div> </body>调用方式:<script type=“text/javascript”> $(’#handout_wrap_inner’).media({ width: ‘100%’, height: ‘100%’, autoplay: true, src:‘http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf', }); </script>方式三: 直接通过页面内嵌iframe$("<iframe src=’"+ this.previewUrl +"’ width=‘100%’ height=‘362px’ frameborder=‘1’>").appendTo($(".video-handouts-preview"));此外还可以在iframe标签之间提供一个提示类似这样<iframe :src=“previewUrl” width=“100%” height=“100%">This browser does not support PDFs. Please download the PDF to view it: <a :href=“previewUrl”>Download PDF</a></iframe>方式四: 通过标签嵌入内容<embed :src=“previewUrl” type=“application/pdf” width=“100%” height=“100%">此标签h5特性中包含四个属性:高、宽、类型、预览文件src!与< iframe > < / iframe > 不同,这个标签是自闭合的的,也就是说如果浏览器不支持PDF的嵌入,那么这个标签的内容什么都看不到!方式五: 标签和iframe使用差别较小<object :src=“previewUrl” width=“100%” height=“100%">This browser does not support PDFs. Please download the PDF to view it: <a :href=“previewUrl”>Download PDF</a></object>方式六: PDFObjectPDFObject实际上也是通过标签实现的直接上代码<!DOCTYPE html><html><head> <title>Show PDF</title> <meta charset=“utf-8” /> <script type=“text/javascript” src=‘pdfobject.min.js’></script> <style type=“text/css”> html,body,#pdf_viewer{ width: 100%; height: 100%; margin: 0; padding: 0; } </style></head><body> <div id=“pdf_viewer”></div></body><script type=“text/javascript”> if(PDFObject.supportsPDFs){ // PDF嵌入到网页 PDFObject.embed(“index.pdf”, “#pdf_viewer” ); } else { location.href = “/canvas”; } // 还可以通过以下代码进行判断是否支持PDFObject预览 if(PDFObject.supportsPDFs){ console.log(“Yay, this browser supports inline PDFs.”); } else { console.log(“Boo, inline PDFs are not supported by this browser”); }</script></html>方式七: PDF.js demoPDF.js可以实现在html下直接浏览pdf文档,是一款开源的pdf文档读取解析插件,非常强大,能将PDF文件渲染成Canvas。PDF.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,一个负责API解析,一个负责核心解析。2、word、xls、ppt文件在线预览功能word、ppt、xls文件实现在线预览的方式比较简单可以直接通过调用微软的在线预览功能实现 (预览前提:资源必须是公共可访问的)<iframe src=‘https://view.officeapps.live.com/op/view.aspx?src=http://storage.xuetangx.com/public_assets/xuetangx/PDF/1.xls' width=‘100%’ height=‘100%’ frameborder=‘1’></iframe>/src就是要实现预览的文件地址//具体文档看这微软接口文档//补充:google的文档在线预览实现同微软(资源必须是公共可访问的)/<iframe :src="‘https://docs.google.com/viewer?url="fileurl"></iframe>3、word文件XDOC可以实现预览以DataURI表示的DOC文档,此外XDOC还可以实现文本、带参数文本、html文本、json文本、公文等在线预览,具体实现方法请看官方文档下面这种方式可以实现快速预览word但是对文件使用的编辑器可能会有一些限制<a href=“http://www.xdocin.com/xdoc?_func=to&_format=html&_cache=1&_xdoc=http://www.xdocin.com/demo/demo.docx" target="_blank” rel=“nofollow”>XDOC</a>4、excel文件目前excel文件已经有了类似pdf.js那样的解析sheet.js总结1、免费纯前端方式实现在线预览word、excel、ppt最优选择微软在线预览(不可编辑)2、利用后端将文件转为图片,前端以图片形式预览(可行方案)3、购买在线预览服务例如百度DOC文档服务、永中、I DOC VIEW等关注微信公众号:生活充电堡 ...

April 9, 2019 · 1 min · jiezi

gitbook 入门教程之导出电子书

gitbook 既可以将源码文件单独输出,也可以仅输出单个文件,常见的导出电子书格式主要有三种(ePub, Mobi, PDF),而这三种格式都依赖于系统本身提供的 ebook-convert 工具.安装依赖如果直接运行 gitbook pdf 相关命令,可能会报错,提示需要安装 ebook-convert 插件,根据提示本地需要安装 calibre 软件,这样 gitbook 才能正常导出电子书.calibre 官网: https://calibre-ebook.com/linux 系统下载地址: https://calibre-ebook.com/dow…下载应用$ sudo -v && wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sudo sh /dev/stdin配置软链接$ sudo ln -s /usr/bin/nodejs /usr/bin/nodemac 系统下载地址: https://calibre-ebook.com/dow…下载应用将 calibre.app 移动到应用程序文件,然后尝试是否能正常打开应用.配置软链接$ sudo ln -s ~/Applications/calibre.app/Contents/MacOS/ebook-convert /usr/bin测试命令$ ebook-convert –version如果没有输出 ebook-convert 版本信息,可能需要配置环境变量.配置封面所有格式的电子书都可以配置自定义封面,在项目的根目录下提供 cover.jpg 和 cover_small.jpg 两种封面图片时,生成电子书会自动增加封面页.当然你也可以使用 autocover 插件 自动生成封面,不过本人才疏学浅,几经尝试始终没有成功,如果有人成功了记得给我留言下哈!封面的基本要求:cover.jpg 尺寸大小: 1800X2360 px,cover_small.jpg 尺寸大小: 200x262 px;无边界清晰可见的书名任何重要的文字在小版本封面图片中也要清晰可见更多封面相关规范请参考 https://toolchain.gitbook.com/ebook.html基本命令语法格式: gitbook pdf 或 gitbook epub 或 gitbook mobi示例:# 生成 pdf 文件并输出 debug 级别日志$ gitbook pdf ./ ./myBook.pdf –log=debug# 生成 epub 文件并输出 debug 级别日志$ gitbook epub ./ ./myBook.epub –log=debug# 生成 mobi 文件并输出 debug 级别日志$ gitbook mobi ./ ./myBook.mobi –log=debug相信大家对 PDF 格式比较熟悉,其余两种格式只是不同电子书格式,因而需要相应软件支持.生成 PDF 文件示例:$ gitbook pdf默认在当前项目的根目录下生成 book.pdf 文件名,如果配有封面,则首页显示封面,否则无封面.生成 ePub 文件示例:$ gitbook epub默认在当前项目的根目录下生成 book.epub 文件名,如果配有封面,则首页显示封面,否则无封面.生成 mobi 文件示例:$ gitbook mobi默认在当前项目的根目录下生成 book.mobi 文件名,如果配有封面,则首页显示封面,否则无封面.小结本节主要介绍了如何导出电子书,概括来说,首先系统需要安装 ebook-convert 工具,然后配置电子书封面,最后直接导出为目标格式(ePub, Mobi, PDF)进行输出.随着电子书内容越来越多,生成电子书所花费的时间也越来越久,实属正常,耐心等待即可.输出 PDF 文件并输出 debug 日志: gitbook pdf –log=debug ...

April 7, 2019 · 1 min · jiezi

用iText读取PDF内容,替换指定内容,输出新PDF

本文介绍怎样用iText,读取PDF内容,以及内容的位置,并替换指定内容,输出新的我的文件主要用到的功能:1.读取PDF内容,以及内容的位置2.复制PDF3.修改PDF,在PDF指定位置输出内容示例代码使用的jar<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13</version></dependency><dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.0.1-jre</version></dependency>public class WordItem { //记录PDF中内容的bean //所在页数 private Integer pageNum; //x坐标 private Float x; //y坐标 private Float y; //内容 private String content; public Integer getPageNum() { return pageNum; } public void setPageNum(Integer pageNum) { this.pageNum = pageNum; } public Float getX() { return x; } public void setX(Float x) { this.x = x; } public Float getY() { return y; } public void setY(Float y) { this.y = y; } public String getContent() { return content; } public void setContent(String content) { this.content = content; }}public class ReplaceWordItem extends WordItem{ //需要替换的关键字,替换后的内容和位置 //文档中搜索的关键字 private String key; //写入的内容 private String value; //偏移的位置 1:上 2:右 3:下面 4:左边 private int site = 2; //偏移的量 private float size = 30; public ReplaceWordItem(String key, String value, float size) { super(); this.key = key; this.value = value; this.size = size; } public ReplaceWordItem() { super(); } public ReplaceWordItem(String key, String value, int site, float size) { super(); this.key = key; this.value = value; this.site = site; this.size = size; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public int getSite() { return site; } public void setSite(int site) { this.site = site; } public float getSize() { return size; } public void setSize(float size) { this.size = size; }}public class KeyWordPositionListener implements RenderListener{ //用来解析PDF内容的类 //页面上所有的词 private List<WordItem> allItems = new ArrayList<WordItem>(); /** * 第几页 / private Integer pageNumber; private WordItem prevItem = new WordItem(); @Override public void beginTextBlock() { // TODO Auto-generated method stub } @Override public void renderText(TextRenderInfo renderInfo) { //读取PDF时,有些肉眼看上去是一行的字,可能会被解析为多个,导致找不到满足条件的关键字,这里做了简单的处理 //即如果一些词是连续的,前后没有空白字符串,即认为是一个词 String content = renderInfo.getText().trim(); Rectangle2D.Float textRectangle = renderInfo.getDescentLine().getBoundingRectange(); System.out.println(“content=” + content + " x="+textRectangle.getX() + " y="+textRectangle.getY()); WordItem item = null; boolean newFlag = false; if(Strings.isNullOrEmpty(prevItem.getContent())) { item = new WordItem(); newFlag = true; }else { if(allItems.size() == 0) { item = new WordItem(); newFlag = true; }else { item = allItems.get(allItems.size()-1); } } //内容会断开,如代理机构名称 变成 代理机构 名称 2个部分???????????? //关键字相关信息 if(!content.equals("")) { if(newFlag) { item.setPageNum(pageNumber); item.setContent(content); item.setX((float)textRectangle.getX()); item.setY((float)textRectangle.getY()); allItems.add(item); //先保存所有的项 }else { //之前有内容 item.setContent(item.getContent() + content); } } prevItem = new WordItem(); prevItem.setContent(content); } @Override public void endTextBlock() { // TODO Auto-generated method stub } @Override public void renderImage(ImageRenderInfo renderInfo) { // TODO Auto-generated method stub } public List<WordItem> getAllItems() { return allItems; } public void setAllItems(List<WordItem> allItems) { this.allItems = allItems; } public Integer getPageNumber() { return pageNumber; } public void setPageNumber(Integer pageNumber) { this.pageNumber = pageNumber; }}public class SearchWord { /* * 从PDF中读取内容 * 内容与关键字比对,如果满足条件,则在匹配内容的指定位置,增加需要显示的内容(替换关键字,修改PDF) / public static void main(String[] args) throws Exception { String path = “in.pdf”; String outPath = “out.pdf”; PdfReader reader = new PdfReader(path); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outPath)); //关键字,以及替换后的内容及位置 List<ReplaceWordItem> keyList = Lists.newArrayList( new ReplaceWordItem(“邮编”, “苏州21510000”, 2), new ReplaceWordItem(“代理机构名称”, “苏州XXX事务所”, 80) ); //找到的位置,匹配到的关键字 List<ReplaceWordItem> keyItemList = matchPage(reader, keyList); //修改PDF for(int i=0; i<keyItemList.size(); i++) { ReplaceWordItem keyItem = keyItemList.get(i); PdfContentByte overContent = stamper.getOverContent(keyItem.getPageNum()); overContent.beginText(); //字体和大小 BaseFont bf = BaseFont.createFont(“C:/Windows/Fonts/simsun.ttc,1”, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); overContent.setFontAndSize(bf, 10F); //位置 overContent.setTextMatrix(keyItem.getX() + keyItem.getSize() + 30, keyItem.getY()); //内容 overContent.showText(keyItem.getValue()); overContent.endText(); } stamper.close(); } /* * 满足关键字的位置 / public static List<ReplaceWordItem> matchPage(PdfReader reader, List<ReplaceWordItem> keywordList) throws Exception { //文档里所有的内容 List<WordItem> allItemList = new ArrayList<>(); for(int page=1; page<=reader.getNumberOfPages(); page++){ KeyWordPositionListener renderListener = new KeyWordPositionListener(); renderListener.setPageNumber(page); PdfReaderContentParser parse = new PdfReaderContentParser(reader); parse.processContent(page, renderListener); Rectangle rectangle = reader.getPageSize(page); System.out.println(rectangle.getWidth() + " " + rectangle.getHeight() + " " + rectangle.getLeft() + " " + rectangle.getRight()); //PageSize.A4 210mm297mm //Itext单位 Pt 1pt = 0.35mm //public static final Rectangle A4 = new RectangleReadOnly(595,842); allItemList.addAll(renderListener.getAllItems()); } for (WordItem wordItem : allItemList) { System.out.println(“wordItem.getContent() " + wordItem.getContent()); } List<ReplaceWordItem> keyItemList = new ArrayList<>(); //那些满足关键字 for (ReplaceWordItem key : keywordList) { for (WordItem pageItem : allItemList) { if(Objects.equal(key.getKey(), pageItem.getContent())) { key.setPageNum(pageItem.getPageNum()); key.setX(pageItem.getX()); key.setY(pageItem.getY()); keyItemList.add(key); //找到第一个就结束 break; } } } return keyItemList; }} ...

April 4, 2019 · 3 min · jiezi

把HTML转成PDF的4个方案及实现

翻译:疯狂的技术宅原文:https://blog.risingstack.com/…本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜的前端技术文章在本文中,我将展示如何使用 Node.js、Puppeteer、headless Chrome 和 Docker 从样式复杂的 React 页面生成 PDF 文档。背景:几个月前,一个客户要求我们开发一个功能,用户可以得到 PDF 格式的 React 页面内容。该页面基本上是患者病例的报告和数据可视化结果,其中包含许多 SVG。另外还有一些特殊的请求来操纵布局,并对 HTML 元素进行一些重新排列。因此与原始的 React 页面相比,PDF 中应该有不同的样式和额外的内容。由于这个任务比用简单的 CSS 规则解决要复杂得多,所以我们先探讨了可能的实现方法。我们找到了 3 个主要解决方案。这篇博文将指导你了解它们的可能性并最终实施。目录:在客户端还是服务器端生成?方案1:从 DOM 制作屏幕截图方案2:仅使用 PDF 库最终方案3:Node.js、Puppeteer 和 Headless Chrome样式控制将文件发送到客户端并保存在 Docker 中使用 Puppeteer方案3 +1:CSS打印规则总结在客户端还是服务器端生成?在客户端和服务器端都可以生成PDF文件。但是让后端处理它可能更有意义,因为你并不想耗尽用户浏览器可以提供的所有资源。即便如此,我仍然会展示这两种方法的解决方案。方案1:从 DOM 制作屏幕截图乍一看,这个解决方案似乎是最简单的,事实证明的确是这样,但它有其自身的局限性。如果你没有特殊需求,例如在 PDF 中选择文本或对文本进行搜索,那么这就是一种简单易用的方法。此方法简单明了:从页面创建屏幕截图,并把它放到 PDF 文件中。非常直截了当。我们可以使用两个包来实现:Html2canvas,根据 DOM 生成截图jsPdf,一个生成PDF的库开始编码:npm install html2canvas jspdfimport html2canvas from ‘html2canvas’import jsPdf from ‘jspdf’ function printPDF () { const domElement = document.getElementById(‘your-id’) html2canvas(domElement, { onclone: (document) => { document.getElementById(‘print-button’).style.visibility = ‘hidden’}}) .then((canvas) => { const img = canvas.toDataURL(‘image/png’) const pdf = new jsPdf() pdf.addImage(imgData, ‘JPEG’, 0, 0, width, height) pdf.save(‘your-filename.pdf’)})就这样!请注意 html2canvas 的 onclone方法。当你在截图之前需要操纵 DOM(例如隐藏打印按钮)时,它是非常方便的。我看到过很多使用这个包的项目。但不幸的是,这不是我们想要的,因为我们需要在后端完成对 PDF 的创建工作。方案2:只使用 PDF 库NPM上有几个库,如 jsPDF(如上所述)或PDFKit。他们的问题是,如果我想使用这些库,我将不得不重新调整页面结构。这肯定会损害可维护性,因为我需要将所有后续更改应用到 PDF 模板和 React 页面中。请看下面的代码。你需要亲自手动创建 PDF 文档。你需要遍历 DOM 并找出每个元素并将其转换为 PDF 格式,这是一项繁琐的工作。必须找到一个更简单的方法。doc = new PDFDocumentdoc.pipe fs.createWriteStream(‘output.pdf’)doc.font(‘fonts/PalatinoBold.ttf’) .fontSize(25) .text(‘Some text with an embedded font!’, 100, 100) doc.image(‘path/to/image.png’, { fit: [250, 300], align: ‘center’, valign: ‘center’}); doc.addPage() .fontSize(25) .text(‘Here is some vector graphics…’, 100, 100) doc.end()这段代码段来自 PDFKit 文档。但是如果你的目标是直接生成一个 PDF 文件,而不是对一个已经存在的(并且不断变化的)HTML 页面进行转换,它还是很有用的。最终方案3:基于 Node.js 的 Puppeteer 和 Headless Chrome什么是 Puppeteer?其文档中写道:Puppeteer 是一个 Node 库,它提供了一个高级 API 来控制 DevTools 协议上的 Chrome 或 Chromium。 Puppeteer 默认以 headless 模式运行 Chrome 或 Chromium,但其也可以被配置为完整的(non-headless)模式运行。它本质上是一个可以从 Node.js 运行的浏览器。如果你读过它的文档,其中首先提到的就是你可以用 Puppeteer 来生成页面的截图和PDF。优秀!这正是我们想要的。先用 npmi i puppeteer 安装 Puppeteer,并实现我们的功能。const puppeteer = require(‘puppeteer’) async function printPDF() { const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); await page.goto(‘https://blog.risingstack.com’, {waitUntil: ’networkidle0’}); const pdf = await page.pdf({ format: ‘A4’ }); await browser.close(); return pdf})这是一个简单的功能,可导航到 URL 并生成站点的 PD F文件。首先,我们启动浏览器(仅在 headless 模式下支持 PDF 生成),然后打开新页面,设置视口,并导航到提供的URL。设置 waitUntil:’networkidle0’ 选项意味着当至少500毫秒没有网络连接时,Puppeteer 会认为导航已完成。 (可以从 API docs 获取更多信息。)之后,我们将 PDF 保存为变量,关闭浏览器并返回 PDF。注意:page.pdf 方法接收 options 对象,你可以使用 ‘path’ 选项将文件保存到磁盘。如果未提供路径,则 PDF 将不会被保存到磁盘,而是会得到缓冲区。(稍后我将讨论如何处理它。)如果需要先登录才能从受保护的页面生成 PDF,首先你要导航到登录页面,检查表单元素的 ID 或名称,填写它们,然后提交表单:await page.type(’#email’, process.env.PDF_USER)await page.type(’#password’, process.env.PDF_PASSWORD)await page.click(’#submit’)要始终将登录凭据保存在环境变量中,不要硬编码!样式控制Puppeteer 也有这种样式操作的解决方案。你可以在生成 PDF 之前插入样式标记,Puppeteer 将生成具有已修改样式的文件。await page.addStyleTag({ content: ‘.nav { display: none} .navbar { border: 0px} #print-button {display: none}’ })将文件发送到客户端并保存好的,现在你已经在后端生成了一个 PDF 文件。接下来做什么?如上所述,如果你不把文件保存到磁盘,将会得到一个缓冲区。你只需要把含有适当内容类型的缓冲区发送到前端即可。printPDF.then(pdf => { res.set({ ‘Content-Type’: ‘application/pdf’, ‘Content-Length’: pdf.length }) res.send(pdf)现在,你只需在浏览器向服务器发送请求即可得到生成的 PDF。function getPDF() { return axios.get(${API_URL}/your-pdf-endpoint, { responseType: ‘arraybuffer’, headers: { ‘Accept’: ‘application/pdf’ } })一旦发送了请求,缓冲区的内容就应该开始下载了。最后一步是将缓冲区数据转换为 PDF 文件。savePDF = () => { this.openModal(‘Loading…’) // open modal return getPDF() // API call .then((response) => { const blob = new Blob([response.data], {type: ‘application/pdf’}) const link = document.createElement(‘a’) link.href = window.URL.createObjectURL(blob) link.download = your-file-name.pdf link.click() this.closeModal() // close modal }) .catch(err => /** error handling **/) }<button onClick={this.savePDF}>Save as PDF</button>就这样!如果单击“保存”按钮,那么浏览器将会保存 PDF。在 Docker 中使用 Puppeteer我认为这是实施中最棘手的部分 —— 所以让我帮你节省几个小时的百度时间。官方文档指出“在 Docker 中使用 headless Chrome 并使其运行起来可能会非常棘手”。官方文档有疑难解答部分,你可以找到有关用 Docker 安装 puppeteer 的所有必要信息。如果你在 Alpine 镜像上安装 Puppeteer,请确保在看到页面的这一部分时再向下滚动一点。否则你可能会忽略一个事实:你无法运行最新的 Puppeteer 版本,并且你还需要用一个标记禁用 shm :const browser = await puppeteer.launch({ headless: true, args: [’–disable-dev-shm-usage’]});否则,Puppeteer 子进程可能会在正常启动之前耗尽内存。方案 3 + 1:CSS 打印规则可能有人认为从开发人员的角度来看,简单地使用 CSS 打印规则很容易。没有 NPM 模块,只有纯 CSS。但是在跨浏览器兼容性方面,它的表现如何呢?在选择 CSS 打印规则时,你必须在每个浏览器中测试结果,以确保它提供的布局是相同的,并且它不是100%能做到这一点。例如,在给定元素后面插入一个 break-after 并不是一个多么高深的技术,但是你可能会惊讶的发现要在 Firefox 中使用它需要使用变通方法。除非你是一位经验丰富的 CSS 大师,在创建可打印页面方面有很多的经验,否则这可能会非常耗时。如果你可以使打印样式表保持简单,打印规则是很好用的。让我们来看一个例子吧。@media print { .print-button { display: none; } .content div { break-after: always; }}上面的 CSS 隐藏了打印按钮,并在每个 div 之后插入一个分页符,其中包含content 类。有一篇很棒的文章总结了你可以用打印规则做什么,以及它们有什么问题,包括浏览器兼容性。考虑到所有因素,如果你想从不那么复杂的页面生成 PDF,CSS打印规则非常有效。总结让我们快速回顾前面介绍的方案,以便从 HTML 页面生成 PDF 文件:从 DOM 产生截图:当你需要从页面创建快照时(例如创建缩略图)可能很有用,但是当你需要处理大量数据时就会有些捉襟见肘。只用 PDF 库:如果你打算从头开始以编程方式创建 PDF 文件,这是一个完美的解决方案。否则,你需要同时维护 HTML 和 PDF 模板,这绝对是一个禁忌。Puppeteer:尽管在 Docker 上工作相对困难,但它为我们的实现提供了最好的结果,而且编写代码也是最简单的。CSS打印规则:如果你的用户受过足够的教育,知道如何把页面内容打印到文件,并且你的页面相对简单,那么它可能是最轻松的解决方案。正如你在我们的案例中所看到的,事实并非如此。打印快乐!本文首发微信公众号:jingchengyideng欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章欢迎继续阅读本专栏其它高赞文章:12个令人惊叹的CSS实验项目世界顶级公司的前端面试都问些什么CSS Flexbox 可视化手册过节很无聊?还是用 JavaScript 写一个脑力小游戏吧!从设计者的角度看 ReactCSS粘性定位是怎样工作的一步步教你用HTML5 SVG实现动画效果程序员30岁前月薪达不到30K,该何去何从7个开放式的前端面试题React 教程:快速上手指南 ...

March 29, 2019 · 3 min · jiezi

用PDFBOX读取PDF内容

PDFBox(一个BSD许可下的源码开放项目)是一个为开发人员读取和创建PDF文档而准备的纯Java类库。主要功能:提取文本,包括Unicode字符和Jakarta Lucene等文本搜索引擎的整合过程十分简单加密/解密PDF文档从PDF和XFDF格式中导入或导出表单数据向已有PDF文档中追加内容将一个PDF文档切分为多个文档覆盖PDF文档示例代码使用的jar<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.14</version></dependency>1.读取PDF内容PDDocument helloDocument = null;try { helloDocument = PDDocument.load(new File(“XXX.pdf”)); PDFTextStripper textStripper = new PDFTextStripper(); System.out.println(textStripper.getText(helloDocument)); helloDocument.close();} catch (IOException e) { e.printStackTrace();}

March 29, 2019 · 1 min · jiezi

fopen(): remote host file access not supported, file://

tp5 使用 TCPD 扩展 将 html 转换为 pdf ,并且保存 pdf 文件报错 : fpen(): remote host file access not supported, file://./parame.pdf利用 TCPD 生成 html 文件 过程1.下载 TCPD 扩展项目跟目录下执行composer require tecnickcom/tcpdf2.控制器测试代码public function pdf(){ $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, ‘UTF-8’, false); $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor(‘Nicola Asuni’); $pdf->SetTitle(‘TCPDF Example 001’); $pdf->SetSubject(‘TCPDF Tutorial’); $pdf->SetKeywords(‘TCPDF, PDF, example, test, guide’); $pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.’ 001’, PDF_HEADER_STRING, array(0,64,255), array(0,64,128)); $pdf->setFooterData(array(0,64,0), array(0,64,128)); $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, ‘’, PDF_FONT_SIZE_MAIN)); $pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, ‘’, PDF_FONT_SIZE_DATA)); $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); $pdf->SetHeaderMargin(PDF_MARGIN_HEADER); $pdf->SetFooterMargin(PDF_MARGIN_FOOTER); $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); if (@file_exists(dirname(FILE).’/lang/eng.php’)) { require_once(dirname(FILE).’/lang/eng.php’); $pdf->setLanguageArray($l); } $pdf->setFontSubsetting(true); $pdf->SetFont(‘dejavusans’, ‘’, 8, ‘’, true); $pdf->AddPage(); $pdf->setTextShadow(array(’enabled’=>true, ‘depth_w’=>0.2, ‘depth_h’=>0.2, ‘color’=>array(196,196,196), ‘opacity’=>1, ‘blend_mode’=>‘Normal’)); $html = <<<EOD<h1>Welcome to <a href=“http://www.tcpdf.org” style=“text-decoration:none;background-color:#CC0000;color:black;">&nbsp;<span style=“color:black;">郭艳</span><span style=“color:white;">BOSS</span>&nbsp;</a>!</h1><i>This is the first example of TCPDF library.</i><p>This text is printed using the <i>writeHTMLCell()</i> method but you can also use: <i>Multicell(), writeHTML(), Write(), Cell() and Text()</i>.</p><p>Please check the source code documentation and other examples for further information.</p><p style=“color:#CC0000;">TO IMPROVE AND EXPAND TCPDF I NEED YOUR SUPPORT, PLEASE <a href=“http://sourceforge.net/donate/index.php?group_id=128076">MAKE A DONATION!</a></p>EOD; $pdf->writeHTMLCell(0, 0, ‘’, ‘’, $html, 0, 1, 0, true, ‘’, true); $filaName = Config::get(‘parame.pdf_ulr’). ‘./example_002.pdf’; //保存 pdf 方式一 : //$count = $pdf->Output($filaName, ‘F’);exit; $count = $pdf->Output(’./parame.pdf’, ‘F’);exit; //保存pdf 方式二 : //$count = $pdf->Output(’example_001.pdf’, ‘S’); //file_put_contents(’./example_001.pdf’,$count);exit; //$pdf->Output(’example_001.pdf’, ‘F’);exit; //$pdf->Output(’./example_001.pdf’, ‘I’);exit; //下载 pdf //$pdf->Output(’./example_001.pdf’, ‘D’); }就这样执行时:报如下错误信息看到网上的解决方案 :参考资料 : https://www.e-learn.cn/conten…可以使用 :$pdf->Output(DIR . ‘/invoices/Delivery Note.pdf’, ‘F’);我发现的问题是 fopen() 函数打开文件或者 URL。如果打开文件 : 则必须是 该文件的 绝对路径 ok 问题解决 !!!!! ...

March 28, 2019 · 2 min · jiezi

PDF文件如何转成markdown格式

百度上根据pdf转makrdown为关键字进行搜索,结果大多数是反过来的转换,即markdown文本转PDF格式。但是PDF转markdown的解决方案很少。正好我工作上有这个需求,所以自己实现了一个解决方案。下图是一个用PDF XChange Editor打开的PDF文件,我想将其内容通过markdown格式导出。(1) 首先将该PDF导出成word格式,后缀.docx(2) 使用typora获得该word文档的markdown源代码:此时任务只完成了一半,因为typora这个工具转换成的markdown格式,如果原始的word文档里包含图片,这些图片以本地图片的形式存在于markdown里,那我如果直接将包含了这些本地图片的标签的markdown发布到简书,CSDN,开源中国,腾讯云,阿里云这些支持markdown的社区时,这些本地图片将无法显示。因此我们必须找到一个高效的方法,将word里包含的本地图片先上传到网络上,再用生成的包含了图片网络url的markdown标签替换本地图片标签。(3) 把word文件的后缀从.docx改成.zip, 解压后,在文件夹word的子文件夹media里能找到所有的本地文件。把这些本地文件全部上传到网站,生成下面这些url:我写了一个工具,可以把仅包含了本地图片标签的markdown源代码和包含了上述在线图片url标签的源代码做一个合并,后并后,本地图片标签会被在线图片标签取代:这个工具可以从我github上获得:https://github.com/i042416/Kn…下图就是我的原始PDF转换成markdown格式后发布在某社区上的效果,和原始PDF外观完全一致:要获取更多Jerry的原创文章,请关注公众号"汪子熙":

February 24, 2019 · 1 min · jiezi

html中在线预览pdf文件之pdf在线预览插件

html中在线预览pdf文件之pdf在线预览插件最近遇到一个需求,要在html页面查看pdf生成的pdf文件!翻来覆去找到两种办法 ,最后采用了jquery.media.js插件方式一将pdf转为图片保存,然后再把图片的地址发到页面进行显示。遇到的困难,pdf转为图片时中文可能会乱码!缺点:生成图片会占用服务器内存。方式二通过js插件在线预览pdf (这里推荐第3中插件)js插件有三种1 pdf.js下载地址https://github.com/mozilla/pd…提供两种使用方式PDF.js可以实现在html下直接浏览pdf文档,是一款开源的pdf文档读取解析插件,非常强大,能将PDF文件渲染成Canvas。PDF.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,一个负责API解析,一个负责核心解析。感兴趣请查看这篇博客https://www.cnblogs.com/zhang…缺点官网项目文件过多,不太容易理解。看着头就大!pdfobject.js使用教程 http://www.jq22.com/jquery-in…缺点pdfobject.js 对浏览器有要求,可能出现不能加载pdf文件,今天我的谷歌浏览器上死活无法显示pdf文件无赖又换了其他的。可能会报错not allow to load resource3 jquery.media.js简单轻量,引入js 然后加载路径即可。使用教程 http://www.jq22.com/jquery-in…下载地址jquery.media.rar(解压密码:www.crowsong.xyz): http://waternote.ctfile.net/f… 用法如下:使用方法引用所需两个文件使用方法首先要引入js文件<script type=“text/javascript” src=“jquery-1.7.1.min.js”></script> <script type=“text/javascript” src=“jquery.media.js”></script>其次添加页面加载完毕后需要执行的js代码,以预览PDF为例:<script type=“text/javascript”> $(function() { $(‘a.media’).media({width:‘100%’, height:900px;}); });</script>最后添加HTML代码:<div class=“panel-body”> <a class=“media” href="/2883353877031485959.pdf"></a></div>将插件中HTML页面中的a标签下href改为想要的pdf地址即可。

January 31, 2019 · 1 min · jiezi

利用命令行工具pdfimages来提取PDF中的图片

pdfimages是一个非常简便好用的PDF图片提取工具,很简单的一个命令就可以提取出PDF指定页面里的所有图片。但是,注意:pdfimages只能提取PDF中的图片,和imagemagick的生成图片有本质上的不同!也就是说,如果PDF中的内容不是图片的话,那么就提取不出来。安装:pdfimage是poppler-utils工具的一个子集,所以需要安装poppler-utils或poppler才能使用。Mac上,直接homebrew:$ brew install poppler安装好后就可以用pdfimages命令了,用法如下:# 提取出来的图片保存为默认的. ppm格式文件 (图片文件巨大,会比pdf文件大23倍左右)$ pdfimages sample.pdf img_name# 设定提取的图片保存为png格式 (图片大小是3倍左右)$ pdfimages -png sample.pdf img_name# 提取某一页的图片 (last one page)$ pdfimages -l 3 sample.pdf img_name# 提取前几页的图片(first number of pages)$ pdfimages -f 2 sample.pdf img_name提取的图片,会按照指定的位置和名字生成如img_name-000.jpg, img_name-001.jpg, img_name-002.jpg这样的文件,每一个图片都对应着PDF中原始的图片。如果没有图片,则不输出。

January 26, 2019 · 1 min · jiezi

ImageMagick 强大的PDF工具集

ImageMagick是Linux上超强大、功能超丰富的图片处理的命令行工具。而ImageMagick在做PDF相关的工作时,是基于Ghostscript进行处理的。所以两个都要安装。首先确保本机已经安装ImageMagick与Ghostscript, Mac安装:brew install ghostscript imagemagickUbuntu安装:sudo apt-get install -y ghostscript imagemagick# on error: sudo apt-get update安装好后,命令行里就可以调用ImageMagick的一系列命令了,包括:convert常用命令有:#JPG图片转为PNG图片$ convert image.jpg image.png#将图片缩放为50%大小$ convert image.png -resize 50% image2.png#将图片缩放为指定长宽$ convert image.png -resize 640x480 image2.png#横向合并图片$ convert image1.png image2.png image3.png +append image123.pngPDF转图片用imagemagick将pdf转成图片(不是提取图片)的命令是:$ convert sample.pdf sample.jpg命令非常简单,速度也极快。但是在PDF转图片的过程中,如果不加任何设置直接convert xx.pdf xx.png这样的转换,效果可是非常之差,如下图:注意:一般如果设置输出为png的话,程序会提出警告:convert: profile ‘icc’: ‘RGB ‘: RGB color space not permitted on grayscale PNG sample-default-convert.png’ @ warning/png.c/MagickPNGWarningHandler/1744.这是因为程序没有很好支持PNG格式图片的问题。虽然报错,但是png文件也能正常生成。如果不喜欢的话,就改成JPG格式输出好了。清晰度设置convert命令将PDF转图片的最大难度在于清晰度问题。网上有很多种解决方案,各有优缺。以下为一些尝试的总结:# 默认转换:图片大小几乎与pdf相同$ convert sample.pdf sample.jpg# resize设置:无论resize 100还是3000,都没有清晰化$ convert -resize 3000 sample.pdf sample.jpg# quality设置:完全没有作用$ convert -quality 100% sample.pdf sample.jpg# verbose+density+quality+flatten+sharpen转换:也就大概还原了80%的清晰度$ convert -verbose -density 150 -trim -quality 100 -flatten -sharpen 0x1.0 sample.pdf sample.jpg# density 300转换:100%还原,但是文件增大10倍$ convert -density 300 -trim -quality 100 sample.pdf sample.jpg# geometry 转换:100%还原,文件增大7倍$ convert -geometry 1600x1600 -density 200x200 -quality 100 sample.pdf sample.jpg总结:经过各种考察,中外网友对convert转换图片的清晰度设置,也全都在猜的阶段。而且设置都太固定,并不能稳定保证所有的PDF都转换成一样的清晰度。所以问题需要转换另一个思路去解决:直接提取PDF中的原画,这样就100%是原画质了。而且一般对于扫描书籍的PDF来说,全页只有一个图片,所以用pdfimages就比较好解决。这个需要另一个命令行工具pdfimages来做到了。请参考另一篇相关笔记。批量图片合并为PDFcd /path/to/images/convert “*.{png,jpeg,jpg}” -quality 100 outfile.pdf ...

January 26, 2019 · 1 min · jiezi

利用命令行工具pdftk对PDF进行合并分割

pdftk是非常好用的PDF页面操作工具,能够切割、合并、提取指定页面等。参考:PDF 合并和分割工具–PDFtk参考官网:PDFtk server: the pdf tool kit常用包括的功能如下:合并 PDF;分割 PDF 页面;旋转 PDF 页面;PDF 带密码访问;PDF 填加密码;用 X/FDF 填写 PDF 表格;从 PDF 表格中生成 PDF Data Stencils;加背景水印或前景印章;报告 PDF Metrics,书签和元数据;增加 / 更新 PDF 书签或元数据;给 PDF 页面或文档加附件;解压 PDF 附件;分解 PDF 文档为多个单页;解压缩和重压缩页面流;修复受损的 PDF 文档;安装Linux上安装:$ sudo apt-get install pdftkMac上安装:因为它对Homebrew支持还不算特别好,需要这样指定文件位置来安装:$ brew install https://raw.githubusercontent.com/turforlag/homebrew-cervezas/master/pdftk.rb常用命令#提取1-15页为一个文件$ pdftk input.pdf cat 1-15 output new.pdf#提取第1至3,第5,第6至10页,并合并为一个pdf文件$ pdftk input.pdf cat 1-3 5 6-10 output combined.pdf#合并(concatenate) 前面所有的pdf为output.pdf$ pdftk file1.pdf file2.pdf … cat output new.pdf#拆分PDF的每一页为一个新文件 并按照指定格式设定文件名$ pdftk input.pdf burst output new_%d.pdf#按照通配符,合并大量PDF文件$ pdftk *.pdf cat output combined.pdf#去除第 13 页,其余的保存为新PDF$ pdftk in.pdf cat 1-12 14-end output out1.pdf#扫描一本书,odd.pdf 为书的全部奇数页,even.pdf 为书的全部偶数页,下面的命令可以将两个 pdf 合并成页码正常的书$ pdftk A=odd.pdf B=even.pdf shuffle A B output collated.pdf#按180°旋转所有页面$ pdftk input.pdf cat 1-endsouth output output.pdf#按顺时针90°旋转第三页,其他页不变$ pdftk input.pdf cat 1-2 3east 4-end output output.pdf#输入密码转换成无密码PDFpdftk secured.pdf input_pw foopass output unsecured.pdf修改PDF的文件结构(目录)大概流程是:提取PDF的目录结构为一个txt文件手动修改txt文件中的目录结构将txt文件重新加载到PDF中并生成一个新文件# 提取信息$ pdftk sample.pdf dump_data output info.txt# 修改信息# …# 把更改的信息加载回PDF$ pdftk sample.pdf update_info info.txt output sample2.pdf ...

January 26, 2019 · 1 min · jiezi

文档资源搜索小工具 - 支持PDF,DOC,PPT,XLS

最近做了一个文档搜索小工具,当然不是网盘搜索工具,这个工具支持四种文件格式搜索(pdf,doc,ppt,xls),你只需要在搜索框中输入你想要搜索资源的关键词,点击搜索按钮即可获取相关资源,点击下载按钮,就可以直接在线浏览和下载。随着搜索关键词次数的增多,可索引到的资源量就越大 。这个工具还有一个【手气不错】的小功能,点击【手气不错】按钮,就可以随机获取一定量的资源,喜欢探索未知资源的小伙伴可以来尝试一下哦。这个工具支持多种国家语言搜索,个人比较喜欢搜索中文和英文的资源。下面是这个工具的屏幕截图以及链接:更多信息Maning文档资源搜索工具

January 16, 2019 · 1 min · jiezi

react下实现一个PDF展示组件

简介:在react的antd-pro的框架下展示本地的PDF文件效果图:一、插件选取。听说过大名鼎鼎的PDF.js,但是因为是在react框架下,所以选取了两个可行的插件react-pdfreact-pdf-js两个插件都是对PDF进行的封装。两个插件都进行了尝试,相对而言react-pdf功能更强大并且文档也比较清晰,但是使用也会相对复杂一点。最后使用的是react-pdf-js这个插件。二、展示选择的文件。react-pdf-js第一步:展示一个本地文档。按照官方的文档:render() { let pagination = null; if (this.state.pages) { pagination = this.renderPagination(this.state.page, this.state.pages); } return ( <div> <PDF file=“test.pdf” onDocumentComplete={this.onDocumentComplete} page={this.state.page} /> {pagination} </div> )}注意:官方文档没有任何说明。此处的file是一个require过来的文件。例子:要加载一个’E:\1.pdf’,那么应该那么配置:const PDFTest = require(‘E:\1.pdf’);render() { let pagination = null; if (this.state.pages) { pagination = this.renderPagination(this.state.page, this.state.pages); } return ( <div> <PDF file={PDFTest} onDocumentComplete={this.onDocumentComplete} page={this.state.page} /> {pagination} </div> )}第二步:根据文件选择框更改文件。这一步被卡住过,刚开始想的是根据选择的文件然后获取文件的实际地址然后运用require去获取文件,但是实现的时候发现浏览器的安全策略无法让浏览器获取文件的真实路径。但是!我们可以通过创建一个URL对象去获取文件的一个blob。使用window.URL.createObjectURL创建一个file文件,并且react-pdf-js可以直接接受一个这样子的文件。部分代码如下:handleButtonOnChange = e =>{ if (e.currentTarget.files.length === 0) return; const url = window.URL.createObjectURL(e.currentTarget.files[0]); this.setState({ pdfTest: { key:url, file:url, }, })}createPDF = () =>{ const { pageNumber, numPages, pdfTest } = this.state; if(!pdfTest) return; return( <div> <div className={style.pdfContainer}> <PDF key={pdfTest.key} file={pdfTest.file} onDocumentComplete={this.onDocumentComplete} page={pageNumber} className={style.pdfView} width=‘300px’ /> </div> <p style={{float:‘right’}}>第 {pageNumber} 页 共 {numPages} 页</p> </div> )}render() { return ( <div id=‘PDFViewer’> <input id=‘id’ type=“file” style={{width:‘200px’,height:‘35px’}} accept=".pdf" onChange={this.handleButtonOnChange} /> {this.createPDF()} </div> );}此处还有一个坑,就是key这个值。在文档中没有提到这个值,并且在源代码中也没有怎么出现这个值。这个key值应该是标识每个文件的一个唯一标识,当key值不同的时候会重新渲染canvas。以下做法不推荐:在之前我没发现这个之前,通过修改源码的这个地方改为:componentWillReceiveProps(newProps) { const { page, scale, file:oldfile, onDocumentComplete, cMapUrl, cMapPacked, } = this.props; const { pdf } = this.state; const { file:newfile } = newProps; if(newfile !== oldfile){ PdfJsLib.GlobalWorkerOptions.workerSrc = ‘//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.worker.js’; PdfJsLib.getDocument({ url: newfile, cMapUrl, cMapPacked }).then((newPdf) => { this.setState({ pdf:newPdf }); if (onDocumentComplete) { onDocumentComplete(newPdf._pdfInfo.numPages); // eslint-disable-line } pdf.getPage(page).then(p => this.drawPDF(p)); }); }else{ if (newProps.page !== page) { pdf.getPage(newProps.page).then(p => this.drawPDF(p)); } if (newProps.scale !== scale) { pdf.getPage(newProps.page).then(p => this.drawPDF(p)); } }}手动实现了这个功能,但是这个判定方法存在一些问题,只有再加入一个变量去判断才会完善,就完全和他的key这个值一样,但是知道key值之后就没有再对源码进行修改了。第三笔:其他功能。翻页以及跳页:handleTurnPage = e =>{ const { pageNumber, numPages, turnPageNumber } = this.state; if(!numPages){ message.warning(‘请先选择PDF文件’); return; } let newPageNumber = pageNumber; switch (e.target.id) { case ‘pageUp’: newPageNumber -= 1; if(newPageNumber <= 0){ message.warning(‘已经是第一页’); return; } break; case ‘pageDown’: newPageNumber += 1; if(newPageNumber > numPages){ message.warning(‘已经是最后一页’); return; } break; case ’numberPage’: if(!turnPageNumber){ message.warning(‘请先输入数字’); return; }else if(turnPageNumber <= 0||turnPageNumber > numPages){ message.warning(‘请输入在页面范围内的数字’); return; } newPageNumber = turnPageNumber; break; default: break; } this.setState({ pageNumber:newPageNumber, })}render() { return ( <div id=‘PDFViewer’> <input id=‘id’ type=“file” style={{width:‘200px’,height:‘35px’}} accept=".pdf" onChange={this.handleButtonOnChange} /> <div style={{float:‘right’}}> <InputNumber onChange={this.onPageNumberInputChange} style={{width:‘150px’}} placeholder=‘输入需要跳转的页’ /> <Button onClick={this.handleTurnPage} id=“numberPage”>确认跳转</Button> <Button onClick={this.handleTurnPage} id=“pageUp”>上一页</Button> <Button onClick={this.handleTurnPage} id=“pageDown”>下一页</Button> </div> {this.createPDF()} </div> );}完整代码:GitHub。react-pdf这个插件的功能很强大,但是使用就相对而言比较复杂。官方的复杂demo由于最后使用的是另外的一个插件。这里就只写一下踩坑记录。1、file参数。在这里file这个参数和react-pdf-js的不一样,在require的时候都是一样的,但是在转换的时候不用创建URL对象,直接将input里面的file传过去即可。并且不需要key。例子:handleButtonOnChange = e =>{ if (e.currentTarget.files.length === 0) return; this.setState({ pdfTest: { file:e.currentTarget.files[0], }, })}2、不显示text layersPDF存在一个问题无法选择里面的文字以及链接,但是PDF.js通过在里面添加一层文本层用于辅助选取,但是在这个插件里面会存在一个重影,导致文字显示效果不佳,如图:在官方文档中提到使用SVG可以解决这个问题,但是SVG选择出来是乱码。所以在使用的时候希望屏蔽掉text layer,在文档中也有提到,在page中设置。以上是所有内容。 ...

January 10, 2019 · 2 min · jiezi

手把手教您将libreoffice移植到函数计算平台

LibreOffice是由文档基金会开发的自由及开放源代码的办公室套件.LibreOffice套件包含文字处理器,电子表格,演示文稿程序,数量库管理程序及创建和编辑数学公式的应用程序。借助LibreOffice的命令行接口可以方便地将office文件转换成pdf。如下所示:$ soffice –convert-to pdf –outdir /tmp /tmp/test.doc一个完整版本的LibreOffice大小为2 GB,而函数计算运行时缓存目录/ tmp空间限制为512M,zip程序包大小限制为50M。好在社区已经有项目aws-lambda-libreoffice成功的将libreoffice移植到AWS Lambda平台,基于前人的方法和经验,本人创建了fc-libreoffice项目,使libreoffice成功的运行在阿里云函数计算平台.fc -libreoffice 在aws-lambda-libreoffice的基础上解决了如下问题:重新编译和裁剪libreoffice,使其适配FC nodejs8 runtime内置的gcc和内核版本;安装运行时缺失的libssl3依赖;借助OSS运行时下载解压,以绕过zip程序包50M的限制;制作了一个例子项目,支持一键部署,快速体验。本文侧重于记述整个移植过程,记录关键步骤以备忘,也为类似的转换工具移植到函数计算平台提供参考。如果您对于如何快速搭建一个廉价且可扩展的词转换pdf云服务更感兴趣,可以阅读另一篇文章“五分钟上线 - 函数计算Word转PDF云服务”。准备工作在开始之前建议找一个台配置较好的Debain / Ubuntu机器,libreoffice编译比较消耗计算资源。并在机器上安装和配置如下工具:docker-ce安装方法参考官方安装文档好玩的一款函数计算的编排工具,用于快速部署函数计算应用。MacOS平台可以使用如下方法安装brew tap vangie/formulabrew install fun其他平台可以通过npm安装npm install @alicloud/fun -gossutil oss的命令行工具。将其下载并放置到&dollar; PATH所在目录。编译libreoffice我们会采用fc-aliyunfc/runtime-nodejs8:build docker 提供的docker镜像进行编译.fc-docker提供了一系列的docker镜像,这些docker镜像环境非常接近函数计算的真实环境。因为我们打算把libreoffice跑在nodejs8环境中,所以我们选用了aliyunfc/runtime-nodejs8:build,建造标签镜像相比于其他镜像会多一些构建需要的基础包。启动一个编译环境通过如下命令可启动一个用于构建libreoffice的容器。docker run –name libre-builder –rm -v $(pwd):/code -d -t –cap-add=SYS_PTRACE –security-opt seccomp=unconfined aliyunfc/runtime-nodejs8:build bash上面的命令,我们启动了一个名为libre-builder的容器并把当前目录挂载到容器内文件系统的/代码目录。附加参数–cap-add=SYS_PTRACE –security-opt seccomp=unconfined是cpp程序编译需要的,否则会报出一些警告。-d表示以后台daemon的方式启动。-t表示启动tty,配合后面的bash命令是为了卡主容器不退出。而–rm表示一旦容器停止了就自动删除容器。安装编译工具接下来进入容器安装编译工具apt-get install -y ccacheapt-get build-dep -y libreofficeccache是一个编译工具,可以加速gcc对同一个程序的多次编译。尽管第一次编译会花费长一点的时间,有了ccache,后续的编译将变得非常非常快。apt-get的build-dep子命令会建立某个要编译软件的环境。具体行为就是把所有依赖的工具和软件包都安装上。克隆源码git clone –depth=1 git://anongit.freedesktop.org/libreoffice/core libreofficecd libreoffice记得加上–depth=1参数,因为libreoffice项目比较大,进行全量克隆会比较费时间,对于编译来说git提交历史没有意义。配置并编译# 如果多次编译,该设置可以加速后续编译ccache –max-size 16 G && ccache -s通过–disable参数去掉不需要的模块,以减少最终编译产物的体积。# the most important part. Run ./autogen.sh –help to see wha each option means./autogen.sh –disable-report-builder –disable-lpsolve –disable-coinmp \ –enable-mergelibs –disable-odk –disable-gtk –disable-cairo-canvas \ –disable-dbus –disable-sdremote –disable-sdremote-bluetooth –disable-gio –disable-randr \ –disable-gstreamer-1-0 –disable-cve-tests –disable-cups –disable-extension-update \ –disable-postgresql-sdbc –disable-lotuswordpro –disable-firebird-sdbc –disable-scripting-beanshell \ –disable-scripting-javascript –disable-largefile –without-helppack-integration \ –without-system-dicts –without-java –disable-gtk3 –disable-dconf –disable-gstreamer-0-10 \ –disable-firebird-sdbc –without-fonts –without-junit –with-theme=“no” –disable-evolution2 \ –disable-avahi –without-myspell-dicts –with-galleries=“no” \ –disable-kde4 –with-system-expat –with-system-libxml –with-system-nss \ –disable-introspection –without-krb5 –disable-python –disable-pch \ –with-system-openssl –with-system-curl –disable-ooenv –disable-dependency-tracking开始编译make的名单最终compile-查询查询结果位于./instdir/目录下。精简尺寸使用strip命令去除二进制文件中的符号信息和编译信息# this will remove ~100 MB of symbols from shared objectsstrip ./instdir/**/删除不必要的文件# remove unneeded stuff for headless moderm -rf ./instdir/share/gallery \ ./instdir/share/config/images_.zip \ ./instdir/readmes \ ./instdir/CREDITS.fodt \ ./instdir/LICENSE* \ ./instdir/NOTICE验证使用如下命令,测试一下编译出来的soffice是否能正常将txt文件转换成pdf文件。echo “hello world” > a.txt./instdir/program/soffice –headless –invisible –nodefault –nofirststartwizard \ –nolockcheck –nologo –norestore –convert-to pdf –outdir $(pwd) a.txt打包# archivetar -zcvf lo.tar.gz instdir然后使用如下命令将lo.tar.gz文件从容器文件系统拷贝到宿主机文件系统。docker cp libre-builder:/code/libreoffice/lo.tar.gz ./lo.tar.gzGzip vs Zopfli vs Brotli Gzip,Zopfli和Brotli是三种开源的压缩算法,对于一个130M的铬文件,分别采用这三种压缩算法最大级别的压缩效果是文件算法MIB压缩比解压耗时铬-130.62–chromium.gzGzip已44.1366.22%0.968schromium.gzZopfli43.0067.08%0.935schromium.brBrotli33.2174.58%0.712s从上面的结果看Brotli算法的效果最优。由于aliyunfc/runtime-nodejs8:build是基于debain jessie发行版的。在debain jessie上安装brotli较为麻烦,所以我们借助ubuntu容器安装brotli工具,将tar.gz格式转为tar.br格式。docker run –name brotli-util –rm -v $(pwd):/root -w /root -d -t ubuntu:18.04 bashdocker exec -t brotli-util apt-get updatedocker exec -t brotli-util apt-get install -y brotlidocker exec -t brotli-util gzip -d lo.tar.gzdocker exec -t brotli-util brotli -q 11 -j -f lo.tar然后当前目录会多一个lo.tar.br文件。安装依赖在函数计算nodejs8环境中运行soffice,需要安装通过npm安装tar.br的解压依赖包@shelf/aws-lambda-brotli-unpacker 和通过apt-get安装libnss3依赖。先启动一个nodejs8的容器,以保证依赖的安装环境和运行时环境是一致的。docker run –rm –name libreoffice-builder -t -d -v $(pwd):/code –entrypoint /bin/sh aliyunfc/runtime-nodejs8注意:存在@shelf/aws-lambda-brotli-unpacker本机绑定,所以在开发机MacOS上npm install打包上传是无法工作。docker exec -t libreoffice-builder npm install由于函数计算运行时无法安装全局的deb包,所以需要将deb和依赖的deb包下载下来,再安装到当前工作目录而不是系统目录。当前工作目录下可以随代码一起打包上传。docker exec -t libreoffice-builder apt-get install -y -d -o=dir::cache=/code libnss3docker exec -t libreoffice-builder bash -c ‘for f in $(ls /code/archives/.deb); do dpkg -x $f $(pwd) ; done;’libnss3包含了许多.so动态链接库文件,linux系统下LD_LIBRARY_PATH环境变量里的动态链接库才能被找到,而函数计算将代码目录/代码下的lib目录默认添加到了LD_LIBRARY_PATH中。所以我们写个脚本,把所有安装的.so文件软连接到/ code / lib目录下docker exec -t libreoffice-builder bash -c “rm -rf /code/archives/; mkdir -p /code/lib;cd /code/lib; find ../usr/lib -type f ( -name ‘.so’ -o -name ‘*.chk’ ) -exec ln -sf {} . ;“下载并解压tar.br为了使用这个lo.tar.br文件,需要先上传到OSSossutil cp $SCRIPT_DIR/../node_modules/fc-libreoffice/bin/lo.tar.br oss://${OSS_BUCKET}/lo.tar.br \ -i ${ALIBABA_CLOUD_ACCESS_KEY_ID} -k ${ALIBABA_CLOUD_ACCESS_KEY_SECRET} -e oss-${ALIBABA_CLOUD_DEFAULT_REGION}.aliyuncs.com -f在函数的初始化方法中下载。module.exports.initializer = (context, callback) => { store = new OSS({ region: oss-${process.env.ALIBABA_CLOUD_DEFAULT_REGION}, bucket: process.env.OSS_BUCKET, accessKeyId: context.credentials.accessKeyId, accessKeySecret: context.credentials.accessKeySecret, stsToken: context.credentials.securityToken, internal: process.env.OSS_INTERNAL === ’true’ }); if (fs.existsSync(binPath) === true) { callback(null, “already downloaded.”); return; } co(store.get(’lo.tar.br’, binPath)).then(function (val) { callback(null, val) }).catch(function (err) { callback(err) });};然后借助于@shelf/aws-lambda-brotli-unpackernpm包解压lo.tar.brconst {unpack} = require(’@shelf/aws-lambda-brotli-unpacker’);const {execSync} = require(‘child_process’);const inputPath = path.join(__dirname, ‘..’, ‘bin’, ’lo.tar.br’);const outputPath = ‘/tmp/instdir/program/soffice’;module.exports.handler = async event => { await unpack({inputPath, outputPath}); execSync(${outputPath} --convert-to pdf --outdir /tmp /tmp/example.docx);};有趣部署函数编写一个template.yml文件,将函数计算的配置都写在该文件中,然后使用fun deploy命令部署函数。ROSTemplateFormatVersion: ‘2015-09-01’Transform: ‘Aliyun::Serverless-2018-04-03’Resources: libre-svc: # service name Type: ‘Aliyun::Serverless::Service’ Properties: Description: ‘fc test’ Policies: - AliyunOSSFullAccess libre-fun: # function name Type: ‘Aliyun::Serverless::Function’ Properties: Handler: index.handler Initializer: index.initializer Runtime: nodejs8 CodeUri: ‘./’ Timeout: 60 MemorySize: 640 EnvironmentVariables: ALIBABA_CLOUD_DEFAULT_REGION: ${ALIBABA_CLOUD_DEFAULT_REGION} OSS_BUCKET: ${OSS_BUCKET} OSS_INTERNAL: ’true’真实场景下,把秘钥和一起变量写在template.yml里并不合适。为了做到代码和配置相分离,上面使用了变量占位符${ALIBABA_CLOUD_DEFAULT_REGION}和${OSS_BUCKET}。然后使用envsubst进行替换SCRIPT_DIR=dirname -- "$0"source $SCRIPT_DIR/../.envexport ALIBABA_CLOUD_DEFAULT_REGION OSS_BUCKETenvsubst < $SCRIPT_DIR/../template.yml.tpl > $SCRIPT_DIR/../template.ymlcd $SCRIPT_DIR/../上面所有的配置都写在了.env文件中,dotenv是社区常见的方案,也有广泛的工具支持。小结本文重点介绍了编译libreoffice的过程,这也是移植中较为困难的部分。由于libreoffice又涉及到npm的本地绑定和apt-get安装到本地目录的问题,所以在函数计算依赖方面本例也是非常经典的场景。无论是编译还是依赖安装,本文中的步骤都强烈地依赖fc-docker镜像,正因为有了该镜像,解决了环境差异问题,大大降低了移植的难度。大文件运行时加载也是函数计算的常见问题,对于转换工具场景中常见的大文件是二进制程序,对于机器学习场景中大文件常是训练模型的数据问题,但是无论是哪一种,采用OSS下载解压的方法都是通用的,随着函数计算支持了NAS,使用NAS挂载共享网盘的方式也是一种新的路径。上文完整的源码可以在FC-LibreOffice的项目中找到。参考阅读https://zh.wikipedia.org/wiki/LibreOffice如何在AWS Lambda中运行LibreOffice以获得大规模的廉价PDFhttps://github.com/alixaxel/chrome-aws-lambdahttps://github.com/shelfio/aws-lambda-brotli-unpacker本文作者:倚贤阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

December 3, 2018 · 3 min · jiezi

发布一个react组件——react-read-pdf,用于在移动端展示PDF文件

PC端的浏览器对于PDF文件的展示没有太大的问题,给定一个PDF的链接,就可以用浏览器默认的展示样式来展示和渲染PDF文件的内容。比如一个"http://www.baidu.com/test/pdf"。 如何在移动端展示这个文件。为了在移动端展示和渲染PDF文件的内容,本文在pdfjs的基础上实现了一个简单的react组件,用于展示和渲染PDF文件。将这个react组件,以npm包的形式发布。这个组件的项目地址为:https://github.com/forthealll…(如果想看使用的例子,直接下载这个代码或者clone,然后npm install和npm start即可)React-read-pdf使用React16.5编写的组件,用于在移动设备和PC端显示和渲染PDF文件特点Simple: 使用简单方便,仅仅是一个react组件Mobile-friendly: 自适应多种移动端的设备,包括手机,平板和其他的移动办公设备浏览器支持IE 10+Firefox 3.6+Chrome 6+Safari 6+Opera 11.5+iOS Safari 6.1+Android Browser 3+快速开始1. 将 react-read-pdf引入你的react项目中(在你的项目中比如先引入react,且必须保证React的版本必须在15.0以上)安装react-read-pdf包npm install –save react-read-pdf在PC端建议使用PDFReader:import React from ‘react’;import { PDFReader } from ‘react-read-pdf’;在移动端建议使用MobilePDFReader,可以自适应各种移动设备:import React from ‘react’;import { MobilePDFReader } from ‘react-read-pdf’;2. 引入之后,再来看简单的使用:import { MobilePDFReader } from ‘react-read-pdf’;export default class Test extends Component{ render(){ return <div style={{overflow:‘scroll’,height:600}}> <MobilePDFReader url=“http://localhost:3000/test.pdf”/> </div> }}import ReactDOM from ‘react-dom’;import Test from ‘./test’ReactDOM.render(<Test />, document.getElementById(‘root’));react-read-pdf 自适配于各种不同的移动设备,包括手机、平板和其他移动办公设备,下图是利用react-read-pdf在iphoneX上展示PDF的一个例子。<img src=“https://raw.githubusercontent…; width=“320”>文档react-read-pdf 这个npm包主要包括了两个不同类型的组件 PDFReader 和 MobilePDFReader.???? PDFReaderimport { PDFReader } from ‘react-read-pdf’…<PDFReader url={“http://localhost:3000/test.pdf”} …>PDFReader组件中的属性属性名称 类型 描述 url 字符串或者对象 如果是字符串,那么url表示的是PDF文件的绝对或者相对地址,如果是对象,可以看关于对象属性的具体描述- > url object type data 字符串 用二进制来描述的PDF文件,在javascript中,我们可以通过“atob”,将base64编码的PDF文件,转化为二进制编码的文件。 page 数字 默认值为1,表示应该渲染PDF文件的第几页 scale 数字 决定渲染的过程中视口的大小 width 数字 决定渲染过程中,视口的宽度 showAllPage 布尔值 默认是false,表示不会一次性渲染,只会渲染page的值所指定的那一页。如果这个值为true,则一次性渲染PDF文件所有的页 onDocumentComplete 函数 将PDF文件加载后,可以通过这个函数输出PDF文件的详细信息。这个函数的具体信息如下所示。 function type url PDFReader组件的url属性类型:string : 字符串,表示PDF文件的绝对或者相对地址object : 对象,有下列的属性属性:属性名类型描述url字符串字符串,表示PDF文件的绝对或者相对地址withCredentials布尔值决定请求是否携带cookieonDocumentComplete PDFReader的onDocumentComplete属性Type:function(totalPage)onDocumentComplete的类型是一个函数, 这个函数的第一个参数表示的是PDF文件的总页数。注意事项PDFReader组件的url属性可以是字符串或者是对象。下面两种方式都是被允许的。其一是 : <MobilePDFReader url=“http://localhost:3000/test.pdf”/>另外一种方式是 : <MobilePDFReader url={url:“http://localhost:3000/test.pdf”}/>???? MobilePDFReaderimport { MobilePDFReader } from ‘react-read-pdf’…<MobilePDFReader url={“http://localhost:3000/test.pdf”} …>MobilePDFReader组件中的属性属性名称 类型 描述 url 字符串 如果是字符串,那么url表示的是PDF文件的绝对或者相对地址 page 数字 默认值为1,表示应该渲染PDF文件的第几页 scale 数字或者“auto” 默认值为“auto”,决定渲染的过程中视口的大小,推荐设置成“auto”可以根据移动设备自适应的适配scale minScale 数字 默认值0.25, scale可取的最小值 maxScale 数字 默认值10, scale可取的最大值 isShowHeader 布尔值 默认值为true,为了生动展示,当值为true,有默认自带的头部样式。设置为false可以去掉这个默认的样式。 isShowFooter 布尔值 默认值为true,为了生动展示,当值为true,有默认自带的尾部样式。设置为false可以去掉这个默认的样式。 onDocumentComplete 函数 将PDF文件加载后,可以通过这个函数输出PDF文件的详细信息。这个函数的具体信息如下所示。function type for details onDocumentComplete MobilePDFReader的onDocumentComplete属性类型: 函数function(totalPage,title,otherObj)函数的参数:参数名称类型描述totalPage数字表示PDF文件的总页数title字符串PDF文件的标题otherObj对象PDF文件的其他扩展或者编码信息注意事项scale的默认值为“auto”,强烈推荐将scale的值设置成“auto”,这样可以根据移动设备的大小自适应的改变scale的值。开发者选项React (16.x)Webpack (4.x)Typescript (3.x)Hot Module Replacement (HMR) using React Hot Loader (4.x)Babel (7.x)LessReact-css-modulesusing css-modulesJest - Testing framework for React applicationsProduction build scriptImage loading/minification using Image Webpack LoaderTypescript compiling using Typescript Loader (5.x)Code quality (linting) for Typescript and LESS/CSS.安装Clone/download repoyarn install (or npm install for npm)使用Developmentyarn run start-devBuild app continuously (HMR enabled)App served @ http://localhost:8080Productionyarn run start-prodBuild app once (HMR disabled)App served @ http://localhost:3000指令列表CommandDescriptionyarn run start-devBuild app continuously (HMR enabled) and serve @ http://localhost:8080yarn run start-prodBuild app once (HMR disabled) and serve @ http://localhost:3000yarn run buildBuild app to /dist/yarn run testRun testsyarn run lintRun Typescript and SASS linteryarn run lint:tsRun Typescript linteryarn run lint:sassRun SASS linteryarn run start(alias of yarn run start-dev)Note: replace yarn with npm if you use npm. ...

October 25, 2018 · 2 min · jiezi

前端使用puppeteer 爬虫生成《React.js 小书》PDF并合并

1、puppeteer 是什么?puppeteer: Google 官方出品的 headless Chrome node 库puppeteer github仓库puppeteer API官方介绍:您可以在浏览器中手动执行的大多数操作都可以使用Puppeteer完成!生成页面的屏幕截图和PDF。抓取SPA并生成预渲染内容(即“SSR”)。自动化表单提交,UI测试,键盘输入等。创建最新的自动化测试环境。使用最新的JavaScript和浏览器功能直接在最新版本的Chrome中运行测试。捕获时间线跟踪 您的网站,以帮助诊断性能问题。测试Chrome扩展程序。2、爬取网站生成PDF2.1 安装 puppeteer// 安装 puppeteer// 可能会因为网络原因安装失败,可使用淘宝镜像 // npm install -g cnpm –registry=https://registry.npm.taobao.orgnpm i puppeteer# or “yarn add puppeteer"2.2 《React.js小书》简介《React.js小书》简介 关于作者@胡子大哈这是⼀本关于 React.js 的⼩书。因为⼯作中⼀直在使⽤ React.js,也⼀直以来想总结⼀下⾃⼰关于 React.js 的⼀些知识、经验。于是把⼀些想法慢慢整理书写下来,做成⼀本开源、免费、专业、简单的⼊⻔级别的⼩书,提供给社区。希望能够帮助到更多 React.js 刚⼊⻔朋友。下图是《React.js 小书》部分截图:2.3 一些可能会用到的 puppeteer API// 新建 reactMiniBook.js, 运行 node reactMiniBook.js 生成pdfconst puppeteer = require(‘puppeteer’);(async () => { // 启动浏览器 const browser = await puppeteer.launch({ // 无界面 默认为true,改成false,则可以看到浏览器操作,目前生成pdf只支持无界面的操作。 // headless: false, // 开启开发者调试模式,默认false, 也就是平时F12打开的面版 // devtools: true, }); // 打开一个标签页 const page = await browser.newPage(); // 跳转到页面 http://huziketang.mangojuice.top/books/react/ await page.goto(‘http://huziketang.com/books/react/', {waitUntil: ’networkidle2’}); // path 路径, format 生成pdf页面格式 await page.pdf({path: ‘react.pdf’, format: ‘A4’}); // 关闭浏览器 await browser.close();})();知道这启动浏览器打开页面关闭浏览器主流程后,再来看几个API。const args = 1;let wh = await page.evaluate((args) => { // args 可以这样传递给这个函数。 // 类似于 setTimeout(() => {console.log(args);}, 3000, args); console.log(‘args’, args); // 1 // 这里可以运行 dom操作等js // 返回通过dom操作等获取到的数据 return { width: 1920, height: document.body.clientHeight, };}, args);// 设置视图大小await page.setViewport(wh);// 等待2sawait page.waitFor(2000);// 以iPhone X执行。const devices = require(‘puppeteer/DeviceDescriptors’);const iPhone = devices[‘iPhone X’];await page.emulate(iPhone);2.4 知道了以上这些API后,就可以开始写主程序了。简单说下:实现功能和主流程。从上面React.js小书截图来看。1、打开浏览器,进入目录页,生成0. React 小书 目录.pdf2、跳转到1. React.js 简介页面,获取左侧所有的导航a链接的href,标题。3、用获取到的a链接数组进行for循环,这个循环里主要做了如下几件事:3.1 隐藏左侧导航,便于生成pdf 3.2 给React.js简介等标题 加上序号,便于查看 3.3 设置docment.title 加上序号, 便于在页眉中使用。 3.4 隐藏 传播一下知识也是一个很好的选择 这一个模块(因为页眉页脚中设置了书的链接等信息,就隐藏这个了) 3.5 给 分页 上一节,下一节加上序号,便于查看。 3.6 最末尾声明下该pdf的说明,仅供学习交流,严禁用于商业用途。 3.7 返回宽高,用于设置视图大小 3.8 设置视图大小,创建生成pdf4、关闭浏览器具体代码:可以查看这里爬虫生成《React.js小书》的pdf每一小节的代码// node 执行这个文件// 笔者这里是:node src/puppeteer/reactMiniBook.js即可生成如下图:每一小节(0-46小节)的pdf生成这些后,那么问题来了,就是查看时总不能看一小节,打开一小节来看,这样很不方便。于是接下来就是合并这些pdf成为一个pdf文件。3、合并成一个PDF文件 pdf-merge起初,我是使用在线网站Smallpdf,合并PDF。合并的效果还是很不错的。这网站还是其他功能。比如word转pdf等。后来找到社区提供的一个npm packagepdf merge 。(毕竟笔者是写程序的,所以就用代码来实现合并了)这个pdf-merge依赖 pdftk安装 PDFtkWindows下载并安装笔者安装后,重启电脑才能使用。Debian, Ubuntu 安装笔者在Ubuntu系统安装后,即可使用。apt-get install pdftk使用例子const PDFMerge = require(‘pdf-merge’);const files = [ ${__dirname}/1.pdf, ${__dirname}/2.pdf,];// Buffer (Default)PDFMerge(files).then((buffer) => {…});// StreamPDFMerge(files, {output: ‘Stream’}).then((stream) => {…});// 笔者这里使用的是这个// Save as new filePDFMerge(files, {output: ${__dirname}/3.pdf}).then((buffer) => {…});知道这些后,可以开始写主程序了。简单说下主流程1、读取到生成的所有pdf文件路径,并排序(0-46)2、判断下输出文件夹是否存在,不存在则创建3、合并这些小节的pdf保存到新文件 React小书(完整版)-作者:胡子大哈-时间戳.pdf具体代码:可以查看这里爬虫生成《React.js小书》的pdf合并pdf的代码最终合并的pdf文件在这里React小书(完整版)-作者:胡子大哈,可供下载。本想着还可以加下书签和页码,没找到合适的生成方案,那暂时先不加了。如果读者有好的方案,欢迎与笔者交流。关于作者:常以轩辕Rowboat为名混迹于江湖。前端路上 | PPT爱好者 | 所知甚少,唯善学。个人博客segmentfault个人主页掘金个人主页知乎github小结1、puppeteer是Google 官方出品的 headless Chrome node 库,可以在浏览器中手动执行的大多数操作都可以使用Puppeteer完成。总之可以用来做很多有趣的事情。2、用 puppeteer 生成每一小节的pdf,用依赖pdftk的pdf-merge npm包, 合并成一个新的pdf文件。或者使用Smallpdf等网站合并。3、《React.js小书》,推荐给大家。爬虫生成pdf,应该不会对作者@胡子大哈有什么影响。作者写书服务社区不易,尽可能多支持作者。最后推荐几个链接,方便大家学习 puppeteer。puppeteer入门教程Puppeteer 初探之前端自动化测试爬虫生成ES6标准入门 pdf大前端神器安利之 Puppeteerpuppeteer API中文文档 ...

August 30, 2018 · 2 min · jiezi