Google क्रोम कन्वर्ट HTML को PDF फीचर्स में समझना


हाल ही में, एक स्टार्टअप में, मैंने पीडीएफ प्रारूप में टिकट बनाने की समस्या को हल किया। उस समय, प्रौद्योगिकियों के एक स्थापित ढेर के साथ एक वेबसाइट पहले से ही तैयार थी, इसलिए मैं एक ऐसे दृष्टिकोण की तलाश में था जिसे अतिरिक्त उपकरणों के उपयोग की आवश्यकता नहीं होगी। अंत में, मैंने पहले HTML प्रारूप में टिकट बनाने का प्रस्ताव रखा, और फिर क्रोम ब्राउज़र का उपयोग करके पीडीएफ में परिवर्तित किया। जैसा कि यह निकला, यह विधि न केवल सीएसएस के साथ बड़े पैमाने पर सजाए गए टिकटों को उत्पन्न कर सकती है, बल्कि जावास्क्रिप्ट में चार्ट के साथ विभिन्न प्रकार की रिपोर्ट भी दे सकती है। इस लेख में, मैं इन उद्देश्यों के लिए Chrome लॉन्च करने के तरीके के बारे में बात करूंगा, CSS को कस्टमाइज़ करने के लिए कुछ सुझाव दूंगा, और इस समाधान के नुकसान पर भी चर्चा करूंगा।


वैकल्पिक विकल्पों पर यहां चर्चा नहीं की जाएगी, क्योंकि उन पर पहले से ही काफी कुछ लिखा जा चुका है, उन्हें ढूंढना आसान है, और वे तैयार उपकरण हैं, जिन पर जानकारी प्राथमिक स्रोतों में देखने के लिए बेहतर है - आधिकारिक वेबसाइटों पर प्रलेखन में। प्रस्तावित विधि एक स्वतंत्र उपकरण नहीं है और कई तकनीकों के विकास के एक उप-उत्पाद की तरह है। इंटरनेट के रूसी-भाषा खंड में, इस पर बहुत कम जानकारी एकत्र की गई है, इसलिए मैंने अंतर को भरने का फैसला किया।


यह विकल्प क्यों चुना गया है?


सबसे बड़ा फायदा यह है कि पीडीएफ को जनरेट करने के लिए क्रोम को प्रौद्योगिकी स्टैक का विस्तार करने की आवश्यकता नहीं है। फ्रंटेंड डेवलपर्स परिचित विकास टूल के साथ HTML बनाते हैं और तुरंत ब्राउज़र में काम के मध्यवर्ती परिणाम देखते हैं। उसी समय, क्रोम शायद परीक्षणों में घूम रहा है और इसे बैकएंड में स्थानांतरित करना मुश्किल नहीं है। यह भी ध्यान दिया जाना चाहिए कि कोडर फ्लेक्सबॉक्स और ग्रिड सहित सीएसएस गुणों के पूरे शस्त्रागार तक पहुंचने में सक्षम है।
मैं लेख के दौरान कमियों और उनके आसपास आने के तरीकों के बारे में बात करूंगा।


हम समस्या को एक पंक्ति में हल करते हैं


कमांड लाइन पर, हम पृष्ठ को पीडीएफ में सहेजने के साथ क्रोम को हेडलेस मोड में कहते हैं:


chrome --headless --disable-gpu --print-to-pdf https://google.com 

लिनक्स उपयोगकर्ताओं को chrome बजाय chromium-browser चलाने की आवश्यकता हो सकती है।
मैक उपयोगकर्ताओं को पूर्व उपनाम बनाने में मददगार हो सकता है:


 alias chrome="/Applications/Google\\ \\Chrome.app/Contents/MacOS/Google\\ \\Chrome" 

अद्यतन: टिप्पणियों ने स्पष्ट किया कि विंडोज उपयोगकर्ताओं को स्पष्ट रूप से पीडीएफ फाइल का नाम सेट करने की आवश्यकता है --print-to-pdf=output.pdf


यदि आपके पास पहले से ही HTML दस्तावेज़ जनरेटर है, तो https://google.com बजाय https://google.com इस दस्तावेज़ को प्राप्त करने के लिए URL निर्दिष्ट करें।


स्थानीय निर्देशिका में फ़ाइल output.pdf खोलें और परिणाम देखें।
आपकी आंख को पकड़ने वाली पहली चीज हैडर की उपस्थिति एक प्रिंट तिथि और एक URL और पृष्ठ पर अंक लगाना के साथ एक पाद लेख की उपस्थिति है। उन्हें हटाने के लिए आपको कुछ CSS नियम जोड़ने होंगे। ये नियम google.com जोड़े जाने की संभावना नहीं है, इसलिए आगे के काम के लिए अपना स्वयं का HTML दस्तावेज़ बनाना बेहतर है।


सीएसएस जोड़ें


CSS में एक विशेष मीडिया क्वेरी @page , जिसका उपयोग प्रिंटिंग के लिए किया जाता है; हम इसमें इंडेंटेशन सेट करेंगे ताकि हैडर और फुटर बस फिट न हों:


 @page { size: A4; margin: 0mm; } 

यह विधि केवल एकल-पृष्ठ दस्तावेज़ों के लिए काम करेगी, जब दो या दो से अधिक पृष्ठों को प्रिंट किया जाता है, तो URL और पृष्ठ क्रमांक वाला पाद लेख निचले तल पर रहेगा। आप स्पष्ट रूप से क्रोम को हेडर और displayHeaderFooter = False के प्रदर्शन को प्रिंट पैरामीटर displayHeaderFooter = False सेट करके बंद करने के लिए कह सकते हैं, लेकिन फिलहाल इसे कमांड लाइन इंटरफेस में नहीं ले जाया जाता है। इसे प्राप्त करने के लिए, आपको ब्राउज़र के साथ काम को स्वचालित करने के लिए उपकरणों की आवश्यकता होगी: सेलेनियम या कठपुतली। अगला, मैं पहले विकल्प पर विचार करूंगा, क्योंकि मेरी परियोजना ने पायथन का उपयोग किया था।


क्रोम को सेलेनियम के माध्यम से लॉन्च करें


तो, सेलेनियम को pip install selenium कमांड के साथ pip install selenium , क्रोम ड्राइवर को डाउनलोड करें जो http://chromedriver.chromium.org/ से क्रोम के आपके संस्करण से मेल खाता है और नीचे दिए गए उदाहरण से get_pdf_from_html फ़ंक्शन का उपयोग करें।


 import sys from selenium import webdriver from selenium.webdriver.chrome.options import Options import json, base64 def get_pdf_from_html(path, chromedriver='./chromedriver', print_options = {}): #  Chrome webdriver_options = Options() webdriver_options.add_argument('--headless') webdriver_options.add_argument('--disable-gpu') driver = webdriver.Chrome(chromedriver, options=webdriver_options) #   url driver.get(path) #    calculated_print_options = { 'landscape': False, 'displayHeaderFooter': False, 'printBackground': True, 'preferCSSPageSize': True, } calculated_print_options.update(print_options) #    pdf  result = send_devtools(driver, "Page.printToPDF", calculated_print_options) driver.quit() #    base64 -  return base64.b64decode(result['data']) def send_devtools(driver, cmd, params={}): resource = "/session/%s/chromium/send_command_and_get_result" % driver.session_id url = driver.command_executor._url + resource body = json.dumps({'cmd': cmd, 'params': params}) response = driver.command_executor._request('POST', url, body) if response['status']: raise Exception(response.get('value')) return response.get('value') if __name__ == "__main__": if len(sys.argv) != 3: print ("usage: converter.py <html_page_sourse> <filename_to_save>") exit() result = get_pdf_from_html(sys.argv[1]) with open(sys.argv[2], 'wb') as file: file.write(result) 

पीडीएफ फाइल प्राप्त करने के लिए, आप पीडीएफ को बचाने के लिए यूआरएल और फ़ाइल नाम निर्दिष्ट करके कमांड लाइन से इस उदाहरण को चला सकते हैं, या get_pdf_from_html फ़ंक्शन को कॉल कर get_pdf_from_html हैं और इसके लिए तीन तर्क पास कर सकते हैं:


  1. पथ - html दस्तावेज़ का url;
  2. क्रोमेड्राइवर - क्रोम चालक को स्थानीय मशीन पर पथ (डिफ़ॉल्ट रूप से, यह स्थानीय निर्देशिका में होना चाहिए);
  3. print_options - अतिरिक्त प्रिंट विशेषताएँ।

यह ध्यान दिया जाना चाहिए कि सेलेनियम में पीडीएफ में एक पृष्ठ को प्रिंट करने के लिए एक मानक इंटरफ़ेस नहीं है, और केवल क्रोम ऐसा कर सकता है, इसलिए आपको सीधे driver.command_executor._request कॉल driver.command_executor._request


अब देखते हैं कि मल्टी-पेज दस्तावेजों पर सामग्री की नियुक्ति को नियंत्रित करने के लिए कौन से उपकरण उपलब्ध हैं।


सीएसएस टाइपोग्राफी


जब द्वैध मुद्रण, आप किनारे से दाएं और बाएं पृष्ठों के लिए अलग-अलग मार्जिन सेट कर सकते हैं यदि आप भविष्य में उन्हें सिलाई करने की योजना बना रहे हैं:


 @page :left { margin-left: 4cm; margin-right: 2cm; } @page :right { margin-left: 4cm; margin-right: 2cm; } 

पहले पृष्ठ के लिए, आप अपना स्वयं का डिज़ाइन निर्दिष्ट कर सकते हैं, उदाहरण के लिए, शीर्ष किनारे से एक बढ़ा हुआ इंडेंट:


 @page :first { margin-top: 10cm /* Top margin on first page 10cm */ } 

प्रथम स्तर के शीर्षक से पहले पृष्ठ विराम को सेट करना संभव है ताकि यह एक विषम पृष्ठ पर शुरू हो:


 h1 { page-break-before : right } 

page-break-after प्रॉपर्टी का उपयोग करके, आप कुछ तत्व के तुरंत बाद पेज ब्रेक को रोक सकते हैं, उदाहरण के लिए, दूसरे स्तर का हेडर:


 h2 { page-break-after : avoid } 

page-break-inside प्रॉपर्टी पेज ब्रेक से बचने में मदद करती है जहां ऐसा करना अवांछनीय है, उदाहरण के लिए एक टेबल के बीच में


 table { page-break-inside : avoid } 

orphans और orphans एक पैराग्राफ की शुरुआत और अंत में पृष्ठ विराम को रोकने में मदद करेंगे:


 @page { orphans:4; widows:2; } 

प्रदर्शन के बारे में क्या?


एक कोर i5-8600K 3600MHz एक स्ट्रीम में, एक साधारण दस्तावेज़ रूपांतरण 0.6 सेकंड लेता है। मेरे अंत -2016 पोर्टेबल टाइपराइटर पर, 2.4 GHz - 1.5 सेकंड।
जाहिर है, मुख्य संसाधनों को ब्राउज़र लॉन्च करने पर खर्च किया जाता है। यदि आप Chrome को एक बार माइक्रोसेवा के रूप में चलाते हैं और उसे रूपांतरण के लिए URL भेजते हैं, तो आप बड़ी संख्या में रूपांतरण समय को कम कर सकते हैं। इस पद्धति का कार्यान्वयन इस लेख के दायरे से परे है।


और क्या गलत है?


मुझे दो मुख्य समस्याएं दिखाई देती हैं:


  1. किसी दस्तावेज़ में तत्वों की स्थिति का निर्धारण करने की असंभवता। इससे पृष्ठ संख्याओं के स्वचालित संकेत के साथ सामग्री की तालिका बनाना मुश्किल हो जाता है, खासकर अगर सामग्री का आकार अग्रिम में ज्ञात नहीं है।
  2. Chrome का रूपांतरण Google का उत्पाद है, जो उपयोगकर्ताओं के बारे में विभिन्न जानकारी एकत्र करता है। यदि दस्तावेज़ से डेटा रिसाव अस्वीकार्य है, तो आपको प्रस्तावित समाधान के बारे में सावधान रहना चाहिए - बाहरी संसाधनों तक पहुंच के साथ ब्राउज़र को बंद करें, या यहां तक ​​कि दूसरे समाधान की तलाश करें। ओपन सोर्स क्रोमियम का उपयोग करने से समस्या हल नहीं होती - Google के बग्स पहले ही इसमें मिल चुके हैं।

निष्कर्ष


मैं अपने दम पर इस दृष्टिकोण का उपयोग करने की स्वीकार्यता पर निष्कर्ष निकालने का प्रस्ताव करता हूं। प्रत्येक परियोजना अपने तरीके से अद्वितीय है। क्या यह विधि आपके प्रोजेक्ट में उपयुक्त है या नहीं।

Source: https://habr.com/ru/post/hi459112/


All Articles