PPTX 생성, 편집 및 분석
.pptx 파일은 XML 파일의 ZIP 아카이브입니다. 작업에 따라 접근 방식을 선택하세요:
| 작업 | 접근 방식 |
|---|---|
| 새 데크 생성 | pptxgenjs 스크립트 작성 — 아래 주의사항 참고 |
| 기존 데크 편집 또는 템플릿 기반 빌드 | 압축 풀기 → ppt/slides/slideN.xml 편집 → 압축 |
| 내용 읽기 | markitdown deck.pptx (<!-- Slide number: N --> 마커 아래 슬라이드당 한 블록); 시각적 그리드: python scripts/thumbnail.py deck.pptx |
스크립트
경로는 이 스킬 디렉터리를 기준으로 합니다. 그 외에는 일반 Python, node 또는 셸입니다.
| 스크립트 | 기능 |
|---|---|
scripts/thumbnail.py deck.pptx [접두사] | 템플릿 레이아웃 선택을 위한 모든 슬라이드의 레이블이 지정된 그리드. .pptx 전용. 접두사를 전달하세요 — 기본값은 thumbnails이며, 같은 디렉터리에서 다른 데크의 그리드를 덮어씁니다 |
scripts/add_slide.py 압축푼폴더/ slide2.xml [--after slideN.xml] | 모든 패키지 관리와 함께 슬라이드(또는 slideLayoutN.xml)를 복제합니다. -o out.pptx와 함께 .pptx를 직접 사용할 수도 있습니다 |
scripts/clean.py 압축푼폴더/ | 더 이상 참조되지 않는 슬라이드, 미디어, rels를 삭제합니다. <p:sldIdLst>가 최종 확정된 후에 실행하세요 |
scripts/office/validate.py deck.pptx [--original src.pptx] | 스키마, 관계, 콘텐츠 유형, 차트 및 슬라이드 검사; 각 실패에 대한 수정 방법을 알려줍니다. 템플릿에서 파생된 데크의 경우 --original을 전달하세요 — 템플릿의 자체 XSD 오류가 사용자 오류로 읽히지 않도록 템플릿에 대해 스키마 검사를 기준화합니다 |
scripts/office/soffice.py --headless --convert-to pdf deck.pptx | LibreOffice 래퍼 — 기본 soffice는 이 샌드박스에서 중단됩니다 |
pptxgenjs로 생성하기 — 주의사항
pptxgenjs는 사전 설치되어 있습니다 — npm install을 실행하지 말고 스크립트를 작성하고 require('pptxgenjs')를 직접 사용하세요. 해당 require가 실패하는 경우에만: npm install pptxgenjs. 모델은 API를 알고 있습니다. 다음은 주의해야 할 사항들입니다:
- 슬라이드를 추가하기 전에
pres.layout을 설정하세요. 기본 캔버스는LAYOUT_16x9= 10" × 5.625" 이며, 13.3" 너비가 아닙니다. 가장자리를 넘는 좌표는 기록되지만 클램프되지 않습니다 — 모양이 슬라이드에 없을 뿐입니다. (LAYOUT_WIDE는 13.3" × 7.5"입니다.) - 16진수 색상: 절대
#를 사용하지 말고, 8자리 숫자를 사용하지 마세요.color: "FF0000"."#FF0000"과 16진수에 알파 값이 포함된 경우("00000020") 모두 파일을 손상시킵니다. 반투명의 경우: 채우기 및 이미지에는transparency: 0-100, 그림자에는opacity: 0.0-1.0을 사용하세요 — 각각 다른 곳에서는 자동으로 무시됩니다. - pptxgenjs는 옵션 객체를 제자리에서 변경합니다 (첫 사용 시 값을 EMU로 변환). 두 개의
add*호출에서 하나의shadow/옵션 객체를 공유하지 마세요 — 매번 새 객체를 만드세요. - 그림자
offset은 ≥ 0이어야 합니다 — 음수 오프셋은 파일을 손상시킵니다. 위쪽으로 그림자를 드리우려면 양수 오프셋과 함께angle: 270을 사용하세요. letterSpacing은 자동으로 무시됩니다 — 실제 옵션은charSpacing입니다.- 목록: 각 항목에
bullet: true를 사용하고, 리터럴•를 절대 사용하지 마세요 (이중 글머리 기호가 렌더링됨). 마지막 항목을 제외한 모든 배열 항목에breakLine: true를 설정하세요. 글머리 기호 단락 사이의 간격은lineSpacing이 아닌paraSpaceAfter를 사용하세요 (간격이 매우 커짐). - 출력 파일당 하나의
new pptxgen()— 인스턴스를 재사용하지 마세요. rectRadius는ROUNDED_RECTANGLE에서만 작동하며,RECTANGLE에서는 작동하지 않습니다.- 그라데이션 채우기는 지원되지 않습니다 — 대신 그라데이션 이미지를 배경으로 사용하세요.
- 텍스트 상자에는 내부 여백이 내장되어 있습니다 — 텍스트가 동일한 x에서 도형, 선 또는 아이콘과 정렬되어야 할 때마다
margin: 0을 설정하세요. - 발표자 노트는
slide.addNotes("...")에 들어갑니다 (일반 텍스트, 슬라이드당 한 번). 슬라이드의 텍스트 상자에 절대 넣지 마세요. - 차트는 기본 형식으로 유지하세요. PowerPoint가 차트로 만들 수 있는 모든 것에 대해
addChart()를 사용하세요 (콤보의 경우{type, data, options}배열 전달). 라이브러리가 노출하지 않는 PowerPoint 기본 기능(추세선, 오차 막대)의 경우 추가 시리즈를 직접 계산하거나 생성된 OOXML을 후처리하세요 — 렌더링된 이미지로 대체하지 마세요. PowerPoint에 기본 형식이 없는 차트 유형(Sankey, 네트워크, 코드)만 이미지로 넣으세요. - 기본 차트는 매우 단순하게 렌더링됩니다 — 제목, 데이터 레이블, 구식 팔레트가 없습니다.
showTitle+title,showValue: true+dataLabelPosition, 팔레트의chartColors: [...]를 설정하고 프레임을 조용하게 만드세요(catAxisLabelColor/valAxisLabelColor,valGridLine: { color, size },catGridLine: { style: "none" }, 단일 시리즈의 경우showLegend: false). - 누적 막대 또는 열 차트에서
dataLabelPosition은ctr,inEnd또는inBase여야 합니다.outEnd는 파일을 손상시킵니다. secondaryValAxis/secondaryCatAxis를 사용하는 콤보 시리즈는 차트 옵션에valAxes와catAxes가 각각 두 개의 항목으로 필요합니다. 이것이 없으면 pptxgenjs는 선언하지 않은 축 id를 작성하고 PowerPoint는 해당 차트를 버리고 파일이 손상되었다고 보고합니다.valAxes만 제공하는 것으로는 충분하지 않습니다.writeFile()후에python scripts/office/validate.py deck.pptx를 실행하세요. 위의 두 가지 차트 결함과 PowerPoint가 거부하는 슬라이드 XML 결함을 보고하고 각각에 대한 수정 방법을 알려줍니다. 패키징된 XML을 수동 편집하지 말고 생성기에서 수정하세요.<p:presentation>의 자식 요소 순서를 절대 변경하지 마세요. pptxgenjs는<p:sldIdLst>바로 뒤에<p:notesMasterIdLst>를 쓰고 두 마스터를 하나의 테마 부분으로 연결합니다. PowerPoint는 이를 정상적으로 읽습니다 — 요소를 이동하면 동일한 데크를 열 수 없게 됩니다.- 아이콘:
react-icons를 SVG로 렌더링(ReactDOMServer.renderToStaticMarkup),sharp로 ≥256px에서 래스터화,addImage({ data: "image/png;base64," + buf.toString("base64") })를 통해 삽입하세요 —image/png;base64,접두사가 필요합니다 (react-icons,react,react-dom,sharp는 사전 설치되어 있음 — require가 실패하는 경우에만npm install react-icons react react-dom sharp실행).
기존 데크 및 템플릿 편집
먼저 레이아웃을 선택하세요: python scripts/thumbnail.py template.pptx template-thumbs는 모든 슬라이드의 레이블이 지정된 그리드를 쓰고 생성된 파일을 출력합니다 — template-thumbs.jpg, 12슬라이드가 넘으면 template-thumbs-N.jpg로 분할됩니다. 항상 데크 이름을 딴 두 번째 인수를 전달하세요. 기본값은 thumbnails이므로 한 디렉터리에서 두 데크의 썸네일을 생성하면 서로의 그리드를 자동으로 덮어씁니다 — 첫 번째 데크의 그리드는 그냥 사라집니다 (템플릿 분석 전용 — 시각적 QA에는 이미지로 변환의 전체 해상도 렌더링이 필요합니다; .pptx만 허용하므로 먼저 .potx를 .pptx 이름으로 복사하세요). markitdown과 함께 사용하여 각 콘텐츠 섹션을 템플릿 슬라이드에 매핑하고 레이아웃을 다양화하세요 — 모든 섹션을 동일한 제목 및 글머리 기호 슬라이드에 넣지 마세요.
python3 -c "import sys,zipfile; zipfile.ZipFile(sys.argv[1]).extractall('unpacked')" deck.pptx
python scripts/add_slide.py unpacked/ slide2.xml --after slide2.xml # 슬라이드(또는 slideLayoutN.xml) 복제; 새 슬라이드 경로 출력
# 슬라이드 재정렬 / 삭제 = ppt/presentation.xml에서 <p:sldIdLst> 편집
python scripts/clean.py unpacked/ # 삭제 후: 고아 슬라이드, 미디어, rels 제거
# ppt/slides/slideN.xml에서 슬라이드 콘텐츠 편집
(cd unpacked && rm -f ../out.pptx && zip -Xr ../out.pptx .) # 디렉터리 내부에서 압축; 먼저 rm 하지 않으면 삭제된 부분이 남습니다
python scripts/office/validate.py out.pptx --original deck.pptx
- 모든 구조적 작업(추가, 삭제, 재정렬)을 슬라이드 콘텐츠 편집 전에 수행하세요.
add_slide.py는 슬라이드 파일을 그대로 복사하므로 편집 후 복제하면 편집된 내용이 복제됩니다. 그리고clean.py는 방금 작성한 슬라이드를 포함하여<p:sldIdLst>에 없는 모든 슬라이드를 삭제합니다. - 슬라이드 파일을 수동으로 복사하지 마세요 —
add_slide.py는 새 슬라이드에 필요한 모든 등록을 수행하고 생성된 내용을 보고합니다 (Created ppt/slides/slide17.xml from slide2.xml). 파일에서 직접 작동할 수도 있습니다:add_slide.py deck.pptx slide2.xml -o out.pptx—-o를 전달하지 않으면 입력 데크를 제자리에서 덮어씁니다. 복제된 슬라이드는 여전히 복제하는 대신 소스의 차트/SmartArt/임베디드 개체 부분을 참조하므로 한 슬라이드의 차트를 편집하면 다른 슬라이드의 차트가 변경됩니다. python-pptx를 사용하는 경우, 세 가지 작업을 수행할 수 없습니다: 슬라이드 복제 (유일한 진입점은add_slide(layout)),text_frame.text = "..."를 통한 서식 유지 (단락을 스타일이 없는 단일 실행으로 축소 — 대신run.text할당), 대부분의 템플릿 아트에 사용되는 SVG/EMF 읽기 (add_picture는UnidentifiedImageError를 발생시킴).- 레거시
.ppt는 먼저 변환해야 합니다:python scripts/office/soffice.py --headless --convert-to pptx file.ppt..potx템플릿은 동일하게 압축 풀기 및 압축됩니다 — 출력에서.potx확장자를 유지하세요. - 템플릿 아이콘이나 이미지를 재사용하려면 이미 포함된 슬라이드나 레이아웃을 복제하세요.
템플릿을 채울 때:
- XML 변환을 스크립팅하는 경우
defusedxml.minidom으로 구문 분석하세요 —xml.etree.ElementTree를 통해 OOXML을 왕복하면 네임스페이스 접두사가 다시 작성되어 데크가 손상됩니다. - 템플릿 슬롯 ≠ 소스 항목. 템플릿에 4명의 팀원이 표시되고 3명만 있는 경우, 4번째 멤버의 전체 그룹(이미지 + 텍스트 상자)을 삭제하고 텍스트만 삭제하지 마세요 — 그런 다음 QA에서 고아 시각적 요소가 있는지 확인하세요.
- 목록 항목당 하나의
<a:p>— 항목을 단일 단락으로 연결하지 마세요. 간격을 유지하려면 형제<a:pPr>를 복사하고 제목, 섹션 머리글 및 인라인 레이블(Status:,Owner:)의<a:rPr>에b="1"을 설정하세요. - 글머리 기호가 레이아웃에서 상속되도록 두세요. 재정의해야 할 경우에만
<a:buChar>,<a:buAutoNum>(번호 매기기) 또는<a:buNone>을 추가하세요 — 텍스트에 리터럴•를 절대 사용하지 마세요. - 앞이나 뒤에 공백이 있는 텍스트는
<a:t>에xml:space="preserve"가 필요합니다.
디자인 아이디어
지루한 슬라이드를 만들지 마세요. 흰색 배경에 일반 글머리 기호는 누구에게도 깊은 인상을 주지 못합니다. 각 슬라이드에 대해 이 목록의 아이디어를 고려하세요.
시작하기 전에
- 대담하고 콘텐츠에 맞는 색상 팔레트를 선택하세요: 팔레트는 이 주제에 맞게 디자인되어야 합니다. 색상을 완전히 다른 프레젠테이션에 적용해도 여전히 "작동"한다면 충분히 구체적인 선택을 하지 않은 것입니다.
- 평등보다는 지배: 하나의 색상이 지배적이어야 합니다 (60-70% 시각적 비중), 1-2개의 보조 색조와 하나의 날카로운 악센트 색상이 있어야 합니다. 모든 색상에 동일한 비중을 절대 주지 마세요.
- 어두움/밝음 대비: 제목 및 결론 슬라이드에는 어두운 배경, 콘텐츠 슬라이드에는 밝은 배경 ("샌드위치" 구조). 또는 프리미엄 느낌을 위해 전체적으로 어두운 배경을 고수하세요.
- 시각적 모티프에 전념하세요: 하나의 독특한 요소를 선택하고 반복하세요 — 둥근 이미지 프레임, 색상 원 안의 아이콘. 모든 슬라이드에 걸쳐 이를 유지하세요. 모티프로 컬러 바나 악센트 줄무늬를 사용하지 마세요 (회피 목록 참조).
색상 팔레트
주제에 맞는 색상을 선택하세요 — 기본 파란색을 사용하지 마세요. 이 팔레트를 영감으로 사용하세요:
| 테마 | 기본 | 보조 | 악센트 |
|---|---|---|---|
| 미드나잇 이그제큐티브 | 1E2761 (네이비) | CADCFC (아이스 블루) | FFFFFF (화이트) |
| 숲과 이끼 | 2C5F2D (포레스트) | 97BC62 (모스) | F5F5F5 (크림) |
| 코랄 에너지 | F96167 (코랄) | F9E795 (골드) | 2F3C7E (네이비) |
| 웜 테라코타 | B85042 (테라코타) | E7E8D1 (샌드) | A7BEAE (세이지) |
| 오션 그라데이션 | 065A82 (딥 블루) | 1C7293 (틸) | 21295C (미드나잇) |
| 차콜 미니멀 | 36454F (차콜) | F2F2F2 (오프 화이트) | 212121 (블랙) |
| 틸 트러스트 | 028090 (틸) | 00A896 (시폼) | 02C39A (민트) |
| 베리 & 크림 | 6D2E46 (베리) | A26769 (더스티 로즈) | ECE2D0 (크림) |
| 세이지 칼름 | 84B59F (세이지) | 69A297 (유칼립투스) | 50808E (슬레이트) |
| 체리 볼드 | 990011 (체리) | FCF6F5 (오프 화이트) | 2F3C7E (네이비) |
각 슬라이드에 대해
모든 슬라이드에는 시각적 요소(이미지, 차트, 아이콘 또는 도형)가 필요합니다. 텍스트만 있는 슬라이드는 기억에 남지 않습니다.
레이아웃 옵션:
- 2열 (텍스트 왼쪽, 일러스트레이션 오른쪽)
- 아이콘 + 텍스트 행 (색상 원 안의 아이콘, 굵은 제목, 아래 설명)
- 2x2 또는 2x3 그리드 (한쪽에 이미지, 다른 쪽에 콘텐츠 블록 그리드)
- 하프 블리드 이미지 (전체 왼쪽 또는 오른쪽)와 콘텐츠 오버레이
데이터 표시:
- 큰 수치 콜아웃 (아래에 작은 레이블이 있는 큰 숫자 60-72pt)
- 비교 열 (전후, 장단점, 나란히 옵션)
- 타임라인 또는 프로세스 흐름 (번호가 매겨진 단계, 화살표)
시각적 마감:
- 섹션 제목 옆에 있는 작은 색상 원 안의 아이콘
- 주요 통계 또는 태그라인에 대한 이탤릭체 악센트 텍스트
타이포그래피
.pptx에 작성하는 글꼴 이름은 이 환경이 아닌 사용자의 PowerPoint에서 렌더링됩니다. 시각적 QA는 LibreOffice를 통해 렌더링되며, LibreOffice는 가지고 있지 않은 글꼴을 대체합니다 — 그리고 일부 글꼴의 경우 대체 글꼴의 너비가 달라 QA 미리보기에서 실제 데크에는 없는 텍스트 오버플로(또는 맞춤)가 표시될 수 있습니다. QA를 신뢰할 수 있게 유지하려면:
- 안전한 글꼴 (QA에서 실제 너비로 렌더링 그리고 Office와 함께 제공): Arial, Calibri, Cambria, Times New Roman, Courier New, Bookman Old Style, Century Schoolbook. 본문 텍스트와 여백이 중요한 모든 것에 사용하세요.
- 제로 QA 위험으로 개성 있는 헤더: 안전한 세리프 헤더(Cambria, Bookman Old Style, Century Schoolbook)를 안전한 산세리프 본문(Calibri 또는 Arial)과 짝지으세요. 신뢰할 수 있는 오버플로 검사를 포기하지 않고 시각적 대비를 얻을 수 있습니다.
- 사용자가 안전한 목록에 없는 글꼴을 요청하는 경우(예: Georgia 또는 Trebuchet MS): 사용자가 요청한 곳에 사용하되, 해당 컨테이너에 여분의 여유 공간(~10%)을 추가하고 해당 요소의 QA 텍스트 맞춤을 신뢰하지 마세요 — 해당 글꼴의 미리보기는 근사치입니다. 사용자가 지정하지 않은 경우 본문 텍스트에는 안전한 목록의 글꼴을 선호하세요.
- QA 신뢰 불가능한 글꼴 (대체 글꼴의 너비가 다름 — 오버플로 검사가 잘못될 수 있음): Georgia, Trebuchet MS, Impact, Arial Black, Garamond, Consolas, Palatino Linotype. Calibri Light 대체는 환경에 따라 다릅니다. 여유가 있는 제목/악센트에는 괜찮습니다. 이러한 글꼴의 QA 텍스트 맞춤은 신뢰하지 마세요.
- 절대 Aptos를 기본값으로 사용하지 마세요 — Office의 2023 이후 기본값은 여기에 호환 가능한 메트릭 대체가 없으며 또한 이전 Office 설치에는 없으므로 양쪽에서 신뢰할 수 없습니다.
| 요소 | 크기 |
|---|---|
| 슬라이드 제목 | 36-44pt 굵게 |
| 섹션 머리글 | 20-24pt 굵게 |
| 본문 텍스트 | 14-16pt |
| 캡션 | 10-12pt 흐리게 |
…
[번역을 위해 잘림]