Upload html_to_hwp_briefing.py
This commit is contained in:
605
03.Code/업로드용/converters/html_to_hwp_briefing.py
Normal file
605
03.Code/업로드용/converters/html_to_hwp_briefing.py
Normal file
@@ -0,0 +1,605 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
HTML HWP 蹂 (湲고
|
||||||
|
|
||||||
|
)
|
||||||
|
癒몃━留щ━留닿
|
||||||
|
諛⑹ ( 踰 ы )
|
||||||
|
|
||||||
|
lead-box, section, data-table, strategy-grid, qa-grid, bottom-box 吏
|
||||||
|
process-container ( ④
|
||||||
|
pip install pyhwpx beautifulsoup4
|
||||||
|
"""
|
||||||
|
濡
|
||||||
|
from pyhwpx import Hwp 몄) 吏
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
import os
|
||||||
|
Navy
|
||||||
|
留
|
||||||
|
class Config:
|
||||||
|
""" ㅼ """
|
||||||
|
PAGE_WIDTH = 210
|
||||||
|
PAGE_HEIGHT = 297
|
||||||
|
MARGIN_LEFT = 20
|
||||||
|
MARGIN_RIGHT = 20
|
||||||
|
MARGIN_TOP = 20
|
||||||
|
MARGIN_BOTTOM = 15
|
||||||
|
HEADER_LEN = 10
|
||||||
|
FOOTER_LEN = 10
|
||||||
|
CONTENT_WIDTH = 170
|
||||||
|
|
||||||
|
class HtmlToHwpConverter:
|
||||||
|
"""HTML HWP 蹂 (湲고
|
||||||
|
|
||||||
|
)"""
|
||||||
|
|
||||||
|
def __init__(self, visible=True):
|
||||||
|
self.hwp = Hwp(visible=visible)
|
||||||
|
self.cfg = Config()
|
||||||
|
self.colors = {}
|
||||||
|
self.is_first_h1 = True
|
||||||
|
|
||||||
|
#
|
||||||
|
# 珥湲고 諛 대━
|
||||||
|
#
|
||||||
|
|
||||||
|
def _init_colors(self):
|
||||||
|
""" 珥湲고 (Navy 怨
|
||||||
|
)"""
|
||||||
|
self.colors = {
|
||||||
|
'primary-navy': self.hwp.RGBColor(26, 54, 93), # #1a365d
|
||||||
|
'secondary-navy': self.hwp.RGBColor(44, 82, 130), # #2c5282
|
||||||
|
'accent-navy': self.hwp.RGBColor(49, 130, 206), # #3182ce
|
||||||
|
'dark-gray': self.hwp.RGBColor(45, 55, 72), # #2d3748
|
||||||
|
'medium-gray': self.hwp.RGBColor(74, 85, 104), # #4a5568
|
||||||
|
'light-gray': self.hwp.RGBColor(226, 232, 240), # #e2e8f0
|
||||||
|
'bg-light': self.hwp.RGBColor(247, 250, 252), # #f7fafc
|
||||||
|
'border-color': self.hwp.RGBColor(203, 213, 224), # #cbd5e0
|
||||||
|
'badge-safe': self.hwp.RGBColor(30, 111, 63), # #1e6f3f
|
||||||
|
'badge-caution': self.hwp.RGBColor(154, 91, 19), # #9a5b13
|
||||||
|
'badge-risk': self.hwp.RGBColor(161, 43, 43), # #a12b2b
|
||||||
|
'white': self.hwp.RGBColor(255, 255, 255),
|
||||||
|
'black': self.hwp.RGBColor(0, 0, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
def _mm(self, mm):
|
||||||
|
"""諛由щ
|
||||||
|
HWP 濡 蹂몄 HWP 濡 蹂
|
||||||
|
RGB濡 蹂고 ㅼ ( ъ )"""
|
||||||
|
self.hwp.set_font(
|
||||||
|
FaceName='留 怨',
|
||||||
|
Height=size,
|
||||||
|
Bold=bold,
|
||||||
|
TextColor=self.colors.get(color, self.colors['black'])
|
||||||
|
)
|
||||||
|
|
||||||
|
def _set_font(self, size=11, bold=False, hex_color='#000000'):
|
||||||
|
"""고 ㅼ (HEX ъ )"""
|
||||||
|
self.hwp.set_font(
|
||||||
|
FaceName='留 怨',
|
||||||
|
Height=size,
|
||||||
|
Bold=bold,
|
||||||
|
TextColor=self._rgb(hex_color)
|
||||||
|
)
|
||||||
|
|
||||||
|
def _align(self, align):
|
||||||
|
""" ㅼ """
|
||||||
|
actions = {
|
||||||
|
'left': 'ParagraphShapeAlignLeft',
|
||||||
|
'center': 'ParagraphShapeAlignCenter',
|
||||||
|
'right': 'ParagraphShapeAlignRight',
|
||||||
|
'justify': 'ParagraphShapeAlignJustify',
|
||||||
|
}
|
||||||
|
if align in actions:
|
||||||
|
self.hwp.HAction.Run(actions[align])
|
||||||
|
|
||||||
|
def _para(self, text='', size=10, color='black', bold=False, align='left'):
|
||||||
|
"""臾몃 쎌
|
||||||
|
"""
|
||||||
|
self._align(align)
|
||||||
|
self._font(size, color, bold)
|
||||||
|
if text:
|
||||||
|
self.hwp.insert_text(text)
|
||||||
|
self.hwp.BreakPara()
|
||||||
|
|
||||||
|
def _exit_table(self):
|
||||||
|
""" 몄 紐⑤ 醫
|
||||||
|
猷"""
|
||||||
|
self.hwp.HAction.Run("Cancel")
|
||||||
|
self.hwp.HAction.Run("CloseEx")
|
||||||
|
self.hwp.HAction.Run("MoveDocEnd")
|
||||||
|
self.hwp.BreakPara()
|
||||||
|
|
||||||
|
def _setup_page(self):
|
||||||
|
""" ㅼ """
|
||||||
|
try:
|
||||||
|
self.hwp.HAction.GetDefault("PageSetup", self.hwp.HParameterSet.HSecDef.HSet)
|
||||||
|
s = self.hwp.HParameterSet.HSecDef
|
||||||
|
s.PageDef.LeftMargin = self._mm(self.cfg.MARGIN_LEFT)
|
||||||
|
s.PageDef.RightMargin = self._mm(self.cfg.MARGIN_RIGHT)
|
||||||
|
s.PageDef.TopMargin = self._mm(self.cfg.MARGIN_TOP)
|
||||||
|
s.PageDef.BottomMargin = self._mm(self.cfg.MARGIN_BOTTOM)
|
||||||
|
s.PageDef.HeaderLen = self._mm(self.cfg.HEADER_LEN)
|
||||||
|
s.PageDef.FooterLen = self._mm(self.cfg.FOOTER_LEN)
|
||||||
|
self.hwp.HAction.Execute("PageSetup", s.HSet)
|
||||||
|
print(f"[ ㅼ ] щ갚: 醫 {self.cfg.MARGIN_LEFT}mm, {self.cfg.MARGIN_TOP}mm, 깆 ] ㅼ ㅽ : {e}")
|
||||||
|
|
||||||
|
#
|
||||||
|
# 癒몃━留щ━留닿
|
||||||
|
諛⑹
|
||||||
|
|
||||||
|
def _create_header(self, right_text=""):
|
||||||
|
"""癒몃━留
|
||||||
|
(곗륫 )"""
|
||||||
|
print(f" 癒몃━留
|
||||||
|
: {right_text if right_text else '(珥湲고)'}")
|
||||||
|
try:
|
||||||
|
self.hwp.HAction.GetDefault("HeaderFooter", self.hwp.HParameterSet.HHeaderFooter.HSet)
|
||||||
|
self.hwp.HParameterSet.HHeaderFooter.HSet.SetItem("HeaderFooterStyle", 0)
|
||||||
|
self.hwp.HParameterSet.HHeaderFooter.HSet.SetItem("HeaderFooterCtrlType", 0)
|
||||||
|
self.hwp.HAction.Execute("HeaderFooter", self.hwp.HParameterSet.HHeaderFooter.HSet)
|
||||||
|
|
||||||
|
self.hwp.HAction.Run("ParagraphShapeAlignRight")
|
||||||
|
self._set_font(9, False, '#4a5568')
|
||||||
|
if right_text:
|
||||||
|
self.hwp.insert_text(right_text)
|
||||||
|
|
||||||
|
self.hwp.HAction.Run("CloseEx")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" [寃쎄 ] 癒몃━留
|
||||||
|
(醫痢 ㅽ + 곗륫 踰 )")
|
||||||
|
print(f" 瑗щ━留닿린
|
||||||
|
self.hwp.HAction.GetDefault("HeaderFooter", self.hwp.HParameterSet.HHeaderFooter.HSet)
|
||||||
|
self.hwp.HParameterSet.HHeaderFooter.HSet.SetItem("HeaderFooterStyle", 0)
|
||||||
|
self.hwp.HParameterSet.HHeaderFooter.HSet.SetItem("HeaderFooterCtrlType", 1)
|
||||||
|
self.hwp.HAction.Execute("HeaderFooter", self.hwp.HParameterSet.HHeaderFooter.HSet)
|
||||||
|
|
||||||
|
# 2. 醫痢 + 紐 8pt
|
||||||
|
self.hwp.HAction.Run("ParagraphShapeAlignLeft")
|
||||||
|
self._set_font(8, False, '#4a5568')
|
||||||
|
self.hwp.insert_text(left_text)
|
||||||
|
|
||||||
|
# 3. 瑗щ━留リ린
|
||||||
|
self.hwp.HAction.Run("CloseEx")
|
||||||
|
|
||||||
|
# 4. 履쎈 (곗륫 )
|
||||||
|
self.hwp.HAction.GetDefault("PageNumPos", self.hwp.HParameterSet.HPageNumPos.HSet)
|
||||||
|
self.hwp.HParameterSet.HPageNumPos.DrawPos = self.hwp.PageNumPosition("BottomRight")
|
||||||
|
self.hwp.HAction.Execute("PageNumPos", self.hwp.HParameterSet.HPageNumPos.HSet)
|
||||||
|
|
||||||
|
def _new_section_with_header(self, header_text):
|
||||||
|
""" 援ъ 癒몃━留 ㅼ """
|
||||||
|
print(f" 援ъ 癒몃━留 癒몃━留
|
||||||
|
# 諛곌꼍 ㅼ
|
||||||
|
#
|
||||||
|
|
||||||
|
def _set_cell_bg(self, color_name):
|
||||||
|
"""諛곌꼍 ㅼ ( )"""
|
||||||
|
self.hwp.HAction.GetDefault("CellBorderFill", self.hwp.HParameterSet.HCellBorderFill.HSet)
|
||||||
|
pset = self.hwp.HParameterSet.HCellBorderFill
|
||||||
|
pset.FillAttr.type = self.hwp.BrushType("NullBrush|WinBrush")
|
||||||
|
pset.FillAttr.WinBrushFaceStyle = self.hwp.HatchStyle("None")
|
||||||
|
pset.FillAttr.WinBrushHatchColor = self.hwp.RGBColor(0, 0, 0)
|
||||||
|
pset.FillAttr.WinBrushFaceColor = self.colors.get(color_name, self.colors['white'])
|
||||||
|
pset.FillAttr.WindowsBrush = 1
|
||||||
|
self.hwp.HAction.Execute("CellBorderFill", pset.HSet)
|
||||||
|
|
||||||
|
#
|
||||||
|
# HTML 蹂고
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
def _convert_lead_box(self, elem):
|
||||||
|
"""lead-box 蹂듭 湲곗“ 諛 )"""
|
||||||
|
content = elem.find("div")
|
||||||
|
if not content:
|
||||||
|
return
|
||||||
|
|
||||||
|
text = content.get_text(strip=True)
|
||||||
|
text = ' '.join(text.split())
|
||||||
|
print(f" lead-box")
|
||||||
|
|
||||||
|
self.hwp.create_table(1, 1, treat_as_char=True)
|
||||||
|
self._set_cell_bg('bg-light')
|
||||||
|
self._font(11.5, 'dark-gray', False)
|
||||||
|
self.hwp.insert_text(text)
|
||||||
|
self._exit_table()
|
||||||
|
|
||||||
|
def _convert_strategy_grid(self, elem):
|
||||||
|
"""strategy-grid 蹂
|
||||||
|
諛 )"""
|
||||||
|
items = elem.find_all(class_="strategy-item")
|
||||||
|
if not items:
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f" strategy-grid: {len(items)} items")
|
||||||
|
|
||||||
|
self.hwp.create_table(2, 2, treat_as_char=True)
|
||||||
|
|
||||||
|
for i, item in enumerate(items[:4]):
|
||||||
|
if i > 0:
|
||||||
|
self.hwp.HAction.Run("MoveRight")
|
||||||
|
|
||||||
|
self._set_cell_bg('bg-light')
|
||||||
|
|
||||||
|
title = item.find(class_="strategy-title")
|
||||||
|
if title:
|
||||||
|
self._font(10, 'primary-navy', True)
|
||||||
|
self.hwp.insert_text(title.get_text(strip=True))
|
||||||
|
self.hwp.BreakPara()
|
||||||
|
|
||||||
|
p = item.find("p")
|
||||||
|
if p:
|
||||||
|
self._font(9.5, 'dark-gray', False)
|
||||||
|
self.hwp.insert_text(p.get_text(strip=True))
|
||||||
|
|
||||||
|
self._exit_table()
|
||||||
|
|
||||||
|
def _convert_process_container(self, elem):
|
||||||
|
"""process-container 蹂④
|
||||||
|
蹂
|
||||||
|
濡
|
||||||
|
몄)"""
|
||||||
|
steps = elem.find_all(class_="process-step")
|
||||||
|
if not steps:
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f" process-container: {len(steps)} steps")
|
||||||
|
|
||||||
|
rows = len(steps)
|
||||||
|
self.hwp.create_table(rows, 2, treat_as_char=True)
|
||||||
|
|
||||||
|
for i, step in enumerate(steps):
|
||||||
|
if i > 0:
|
||||||
|
self.hwp.HAction.Run("MoveRight")
|
||||||
|
|
||||||
|
# 踰
|
||||||
|
|
||||||
|
num = step.find(class_="step-num")
|
||||||
|
self._set_cell_bg('primary-navy')
|
||||||
|
self._font(10, 'white', True)
|
||||||
|
self._align('center')
|
||||||
|
if num:
|
||||||
|
self.hwp.insert_text(num.get_text(strip=True))
|
||||||
|
|
||||||
|
self.hwp.HAction.Run("MoveRight")
|
||||||
|
|
||||||
|
# 댁
|
||||||
|
|
||||||
|
content = step.find(class_="step-content")
|
||||||
|
self._set_cell_bg('bg-light')
|
||||||
|
self._font(10.5, 'dark-gray', False)
|
||||||
|
self._align('left')
|
||||||
|
if content:
|
||||||
|
self.hwp.insert_text(content.get_text(strip=True))
|
||||||
|
|
||||||
|
self._exit_table()
|
||||||
|
|
||||||
|
def _convert_data_table(self, table):
|
||||||
|
"""data-table 蹂ы )"""
|
||||||
|
data = []
|
||||||
|
|
||||||
|
thead = table.find("thead")
|
||||||
|
if thead:
|
||||||
|
ths = thead.find_all("th")
|
||||||
|
data.append([th.get_text(strip=True) for th in ths])
|
||||||
|
|
||||||
|
tbody = table.find("tbody")
|
||||||
|
if tbody:
|
||||||
|
for tr in tbody.find_all("tr"):
|
||||||
|
row = []
|
||||||
|
for td in tr.find_all("td"):
|
||||||
|
badge = td.find(class_="badge")
|
||||||
|
if badge:
|
||||||
|
badge_class = ' '.join(badge.get('class', []))
|
||||||
|
badge_text = badge.get_text(strip=True)
|
||||||
|
if 'badge-safe' in badge_class:
|
||||||
|
row.append(f"[ {badge_text}]")
|
||||||
|
elif 'badge-caution' in badge_class:
|
||||||
|
row.append(f"[ {badge_text}]")
|
||||||
|
elif 'badge-risk' in badge_class:
|
||||||
|
row.append(f"[ {badge_text}]")
|
||||||
|
else:
|
||||||
|
row.append(f"[{badge_text}]")
|
||||||
|
else:
|
||||||
|
row.append(td.get_text(strip=True))
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
|
||||||
|
rows = len(data)
|
||||||
|
cols = len(data[0]) if data else 0
|
||||||
|
print(f" data-table: {rows} {cols}")
|
||||||
|
|
||||||
|
self.hwp.create_table(rows, cols, treat_as_char=True)
|
||||||
|
|
||||||
|
for row_idx, row in enumerate(data):
|
||||||
|
for col_idx, cell_text in enumerate(row):
|
||||||
|
is_header = (row_idx == 0)
|
||||||
|
is_first_col = (col_idx == 0 and not is_header)
|
||||||
|
|
||||||
|
is_safe = '[ ' in str(cell_text)
|
||||||
|
is_caution = '[ ' in str(cell_text)
|
||||||
|
is_risk = '[ ' in str(cell_text)
|
||||||
|
|
||||||
|
if is_header:
|
||||||
|
self._set_cell_bg('primary-navy')
|
||||||
|
self._font(9, 'white', True)
|
||||||
|
elif is_first_col:
|
||||||
|
self._set_cell_bg('bg-light')
|
||||||
|
self._font(9.5, 'primary-navy', True)
|
||||||
|
elif is_safe:
|
||||||
|
self._font(9.5, 'badge-safe', True)
|
||||||
|
elif is_caution:
|
||||||
|
self._font(9.5, 'badge-caution', True)
|
||||||
|
elif is_risk:
|
||||||
|
self._font(9.5, 'badge-risk', True)
|
||||||
|
else:
|
||||||
|
self._font(9.5, 'dark-gray', False)
|
||||||
|
|
||||||
|
self._align('center')
|
||||||
|
self.hwp.insert_text(str(cell_text))
|
||||||
|
|
||||||
|
if not (row_idx == rows - 1 and col_idx == cols - 1):
|
||||||
|
self.hwp.HAction.Run("MoveRight")
|
||||||
|
|
||||||
|
self._exit_table()
|
||||||
|
|
||||||
|
def _convert_qa_grid(self, elem):
|
||||||
|
"""qa-grid 蹂 諛 )"""
|
||||||
|
items = elem.find_all(class_="qa-item")
|
||||||
|
if not items:
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f" qa-grid: {len(items)} items")
|
||||||
|
|
||||||
|
self.hwp.create_table(1, 2, treat_as_char=True)
|
||||||
|
|
||||||
|
for i, item in enumerate(items[:2]):
|
||||||
|
if i > 0:
|
||||||
|
self.hwp.HAction.Run("MoveRight")
|
||||||
|
|
||||||
|
self._set_cell_bg('bg-light')
|
||||||
|
|
||||||
|
text = item.get_text(strip=True)
|
||||||
|
strong = item.find("strong")
|
||||||
|
if strong:
|
||||||
|
q_text = strong.get_text(strip=True)
|
||||||
|
a_text = text.replace(q_text, '').strip()
|
||||||
|
|
||||||
|
self._font(9.5, 'primary-navy', True)
|
||||||
|
self.hwp.insert_text(q_text)
|
||||||
|
self.hwp.BreakPara()
|
||||||
|
self._font(9.5, 'dark-gray', False)
|
||||||
|
self.hwp.insert_text(a_text)
|
||||||
|
else:
|
||||||
|
self._font(9.5, 'dark-gray', False)
|
||||||
|
self.hwp.insert_text(text)
|
||||||
|
|
||||||
|
self._exit_table()
|
||||||
|
|
||||||
|
def _convert_bottom_box(self, elem):
|
||||||
|
"""bottom-box 蹂듭 寃곕 諛 )"""
|
||||||
|
left = elem.find(class_="bottom-left")
|
||||||
|
right = elem.find(class_="bottom-right")
|
||||||
|
|
||||||
|
if not left or not right:
|
||||||
|
return
|
||||||
|
|
||||||
|
left_text = ' '.join(left.get_text().split())
|
||||||
|
right_text = right.get_text(strip=True)
|
||||||
|
print(f" bottom-box")
|
||||||
|
|
||||||
|
self.hwp.create_table(1, 2, treat_as_char=True)
|
||||||
|
|
||||||
|
# 醫痢 (Navy 諛곌꼍)
|
||||||
|
self._set_cell_bg('primary-navy')
|
||||||
|
self._font(10.5, 'white', True)
|
||||||
|
self._align('center')
|
||||||
|
self.hwp.insert_text(left_text)
|
||||||
|
|
||||||
|
self.hwp.HAction.Run("MoveRight")
|
||||||
|
|
||||||
|
# 곗륫 ( 고 諛곌꼍)
|
||||||
|
self._set_cell_bg('bg-light')
|
||||||
|
self._font(10.5, 'primary-navy', True)
|
||||||
|
self._align('center')
|
||||||
|
self.hwp.insert_text(right_text)
|
||||||
|
|
||||||
|
self._exit_table()
|
||||||
|
|
||||||
|
def _convert_section(self, section):
|
||||||
|
"""section 蹂 " + title.get_text(strip=True), 12, 'primary-navy', True)
|
||||||
|
|
||||||
|
strategy_grid = section.find(class_="strategy-grid")
|
||||||
|
if strategy_grid:
|
||||||
|
self._convert_strategy_grid(strategy_grid)
|
||||||
|
|
||||||
|
process = section.find(class_="process-container")
|
||||||
|
if process:
|
||||||
|
self._convert_process_container(process)
|
||||||
|
|
||||||
|
table = section.find("table", class_="data-table")
|
||||||
|
if table:
|
||||||
|
self._convert_data_table(table)
|
||||||
|
|
||||||
|
ul = section.find("ul")
|
||||||
|
if ul:
|
||||||
|
for li in ul.find_all("li", recursive=False):
|
||||||
|
keyword = li.find(class_="keyword")
|
||||||
|
if keyword:
|
||||||
|
kw_text = keyword.get_text(strip=True)
|
||||||
|
full = li.get_text(strip=True)
|
||||||
|
rest = full.replace(kw_text, '', 1).strip()
|
||||||
|
|
||||||
|
self._font(10.5, 'primary-navy', True)
|
||||||
|
self.hwp.insert_text(" " + kw_text + " ")
|
||||||
|
self._font(10.5, 'dark-gray', False)
|
||||||
|
self.hwp.insert_text(rest)
|
||||||
|
self.hwp.BreakPara()
|
||||||
|
else:
|
||||||
|
self._para(" " + li.get_text(strip=True), 10.5, 'dark-gray')
|
||||||
|
|
||||||
|
qa_grid = section.find(class_="qa-grid")
|
||||||
|
if qa_grid:
|
||||||
|
self._convert_qa_grid(qa_grid)
|
||||||
|
|
||||||
|
self._para()
|
||||||
|
|
||||||
|
def _convert_sheet(self, sheet, is_first_page=False, footer_title=""):
|
||||||
|
""" (sheet) 蹂
|
||||||
|
留 癒몃━留щ━留
|
||||||
|
ㅼ
|
||||||
|
if is_first_page:
|
||||||
|
# 癒몃━留
|
||||||
|
|
||||||
|
ㅽ 異異
|
||||||
|
header = sheet.find(class_="page-header")
|
||||||
|
if header:
|
||||||
|
left = header.find(class_="header-left")
|
||||||
|
right = header.find(class_="header-right")
|
||||||
|
# 곗륫
|
||||||
|
ㅽ ъ (遺
|
||||||
|
紐
|
||||||
|
)
|
||||||
|
header_text = right.get_text(strip=True) if right else ""
|
||||||
|
if header_text:
|
||||||
|
self._create_header(header_text)
|
||||||
|
|
||||||
|
# 瑗щ━留紐 + 踰
|
||||||
|
self._create_footer(footer_title)
|
||||||
|
|
||||||
|
# 紐
|
||||||
|
title = sheet.find(class_="header-title")
|
||||||
|
if title:
|
||||||
|
title_text = title.get_text(strip=True)
|
||||||
|
if '[泥⑤ ]' in title_text:
|
||||||
|
self._para(title_text, 15, 'primary-navy', True, 'left')
|
||||||
|
self._font(10, 'secondary-navy', False)
|
||||||
|
self._align('left')
|
||||||
|
self.hwp.insert_text("" * 60)
|
||||||
|
self.hwp.BreakPara()
|
||||||
|
else:
|
||||||
|
self._para(title_text, 23, 'primary-navy', True, 'center')
|
||||||
|
self._font(10, 'secondary-navy', False)
|
||||||
|
self._align('center')
|
||||||
|
self.hwp.insert_text("" * 45)
|
||||||
|
self.hwp.BreakPara()
|
||||||
|
|
||||||
|
self._para()
|
||||||
|
|
||||||
|
# 由щ 諛
|
||||||
|
lead_box = sheet.find(class_="lead-box")
|
||||||
|
if lead_box:
|
||||||
|
self._convert_lead_box(lead_box)
|
||||||
|
self._para()
|
||||||
|
|
||||||
|
#
|
||||||
|
뱀
|
||||||
|
|
||||||
|
for section in sheet.find_all(class_="section"):
|
||||||
|
self._convert_section(section)
|
||||||
|
|
||||||
|
# 諛
|
||||||
|
bottom_box = sheet.find(class_="bottom-box")
|
||||||
|
if bottom_box:
|
||||||
|
self._para()
|
||||||
|
self._convert_bottom_box(bottom_box)
|
||||||
|
|
||||||
|
#
|
||||||
|
# 硫⑥
|
||||||
|
|
||||||
|
def convert(self, html_path, output_path):
|
||||||
|
"""HTML HWP 蹂ㅽ"""
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("HTML HWP 蹂 (湲고
|
||||||
|
|
||||||
|
) ")
|
||||||
|
print(" 癒몃━留щ━留닿
|
||||||
|
諛 Navy
|
||||||
|
留, 湲고
|
||||||
|
")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
print(f"\n[ ] {html_path}")
|
||||||
|
|
||||||
|
with open(html_path, 'r', encoding='utf-8') as f:
|
||||||
|
soup = BeautifulSoup(f.read(), 'html.parser')
|
||||||
|
|
||||||
|
# 紐 異異 (瑗щ━留)
|
||||||
|
title_tag = soup.find('title')
|
||||||
|
if title_tag:
|
||||||
|
full_title = title_tag.get_text(strip=True)
|
||||||
|
footer_title = full_title.split(':')[0].strip()
|
||||||
|
else:
|
||||||
|
footer_title = ""
|
||||||
|
|
||||||
|
self.hwp.FileNew()
|
||||||
|
self._init_colors()
|
||||||
|
self._setup_page()
|
||||||
|
|
||||||
|
# 蹂
|
||||||
|
蹂\n")
|
||||||
|
|
||||||
|
for i, sheet in enumerate(sheets, 1):
|
||||||
|
print(f"[{i}/{total}] 泥 怨...")
|
||||||
|
self._convert_sheet(sheet, is_first_page=(i == 1), footer_title=footer_title)
|
||||||
|
|
||||||
|
if i < total:
|
||||||
|
self.hwp.HAction.Run("BreakPage")
|
||||||
|
|
||||||
|
#
|
||||||
|
self.hwp.SaveAs(output_path)
|
||||||
|
print(f"\n
|
||||||
|
猷: {output_path}")
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""HWP 醫
|
||||||
|
猷"""
|
||||||
|
try:
|
||||||
|
self.hwp.Quit()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
""" ㅽ"""
|
||||||
|
|
||||||
|
html_path = r"D:\for python\geulbeot-light\geulbeot-light\output\briefing.html"
|
||||||
|
output_path = r"D:\for python\geulbeot-light\geulbeot-light\output\briefing.hwp"
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("HTML HWP 蹂 (湲고
|
||||||
|
)")
|
||||||
|
print("=" * 60)
|
||||||
|
print()
|
||||||
|
|
||||||
|
try:
|
||||||
|
converter = HtmlToHwpConverter(visible=True)
|
||||||
|
converter.convert(html_path, output_path)
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print(" 蹂
|
||||||
|
猷!")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
input("\nEnter瑜
|
||||||
|
대㈃ HWP媛 ロ...")
|
||||||
|
converter.close()
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"\n[ ]
|
||||||
|
李얠
|
||||||
|
듬: {html_path}")
|
||||||
|
print("寃쎈瑜 댁<
|
||||||
|
몄.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n[ ] {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user