feat: auto-convert URL to QR code in PDF export and preview
This commit is contained in:
@@ -53,6 +53,26 @@ try:
|
||||
except Exception as e:
|
||||
CHINESE_FONT_OK = False
|
||||
|
||||
import re
|
||||
import qrcode
|
||||
from io import BytesIO
|
||||
from reportlab.platypus import Image as RLImage
|
||||
|
||||
# URL 正则表达式
|
||||
URL_PATTERN = re.compile(r'https?://[^\s<>"{}|\\^`\[\]]+')
|
||||
|
||||
def generate_qr_image(url, size=50*mm):
|
||||
"""生成二维码图片,返回 BytesIO 对象"""
|
||||
qr = qrcode.make(url, box_size=10)
|
||||
buf = BytesIO()
|
||||
qr.save(buf, format='PNG')
|
||||
buf.seek(0)
|
||||
return buf
|
||||
|
||||
def contains_url(text):
|
||||
"""检测文本是否包含 URL"""
|
||||
return bool(URL_PATTERN.search(text))
|
||||
|
||||
def md_to_xml(text):
|
||||
"""将markdown转换为reportlab XML markup"""
|
||||
if not text:
|
||||
@@ -169,9 +189,27 @@ class PianoPDF:
|
||||
self.elements.append(Paragraph(md_to_xml(text), self.heading_style))
|
||||
|
||||
def add_paragraph(self, text):
|
||||
if text:
|
||||
self.elements.append(Paragraph(md_to_xml(text), self.body_style))
|
||||
self.elements.append(Spacer(1, 1*mm))
|
||||
if not text:
|
||||
return
|
||||
|
||||
# 检测是否是纯 URL
|
||||
url_match = URL_PATTERN.match(text.strip())
|
||||
if url_match and url_match.group() == text.strip():
|
||||
# 纯 URL,生成二维码
|
||||
url = url_match.group()
|
||||
try:
|
||||
buf = generate_qr_image(url, 50*mm)
|
||||
img = RLImage(buf, width=50*mm, height=50*mm)
|
||||
img.hAlign = 'CENTER'
|
||||
self.elements.append(img)
|
||||
self.elements.append(Spacer(1, 2*mm))
|
||||
return
|
||||
except Exception as e:
|
||||
# QR生成失败,回退到文字
|
||||
pass
|
||||
|
||||
self.elements.append(Paragraph(md_to_xml(text), self.body_style))
|
||||
self.elements.append(Spacer(1, 1*mm))
|
||||
|
||||
def add_list(self, items):
|
||||
for item in items:
|
||||
|
||||
Reference in New Issue
Block a user