agentsclimarketplace

Excel2md

Skill Dannykkh/skill-olympus/skills/excel2md

Twelve Greek gods. One command. A working SaaS. 98 skills + 49 agents + 13 hooks for Claude Code + Codex CLI + Gemini CLI. Cross-CLI persistent memory, zero-interaction full pipeline (design → build → inspect → test → ship).

Install
npx -y skills add Dannykkh/skill-olympus --skill excel2md

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

.xlsx 엑셀 파일 읽기/변환 전문 스킬. JSON/마크다운 변환, 임베디드 이미지 자동 추출, 시트별 파일 생성. ".xlsx", "엑셀", "excel", "스프레드시트" 요청에 실행.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

5.6 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

Excel to JSON/Markdown

엑셀 파일을 구조화된 JSON 또는 마크다운으로 변환합니다. 임베디드 이미지도 자동 추출하여 해당 행에 매핑합니다.

Quick Start

/excel2md report.xlsx                        # JSON (기본)
/excel2md report.xlsx --format md            # 마크다운
/excel2md data.xlsx --sheet "매출현황"        # 특정 시트
/excel2md data.xlsx --output ./docs          # 출력 디렉토리
/excel2md data.xlsx --no-images              # 이미지 제외

Step 0: 구조 분석 (First Actions)

변환 전 엑셀 파일의 구조를 먼저 파악합니다.

import openpyxl

wb = openpyxl.load_workbook('data.xlsx', data_only=True)
for sheet_name in wb.sheetnames:
    ws = wb[sheet_name]
    print(f"\n=== {sheet_name} ===")
    print(f"  크기: {ws.max_row}행 × {ws.max_column}열")
    print(f"  병합 셀: {len(ws.merged_cells.ranges)}개")
    
    # 헤더 자동 감지 (문자열 비율 기반)
    for row_idx in range(1, min(6, ws.max_row + 1)):
        row = [ws.cell(row_idx, c).value for c in range(1, ws.max_column + 1)]
        str_ratio = sum(1 for v in row if isinstance(v, str)) / max(len(row), 1)
        marker = " ← 헤더 후보" if str_ratio > 0.7 else ""
        print(f"  행 {row_idx}: {row[:5]}...{marker}")

구조 분석 출력 예시

=== Sheet1 ===
  크기: 150행 × 8열
  병합 셀: 3개
  행 1: ['번호', '이름', '부서', '직급', '입사일']... ← 헤더 후보
  행 2: [1, '김철수', '개발팀', '대리', datetime(2020,3,1)]...

=== 매출현황 ===
  크기: 50행 × 12열
  병합 셀: 12개 (그룹 헤더)
  행 1: ['', '', '2025년', None, None, '2026년']... ← 그룹 헤더
  행 2: ['지역', '담당자', '1Q', '2Q', '3Q', '1Q']... ← 실제 헤더

Step 1: 데이터 타입 감지 + 변환

타입별 처리 규칙

엑셀 타입JSON 출력MD 출력
문자열"text"text (파이프·줄바꿈 이스케이프)
정수123천 단위 콤마 1,234
소수3.141,234.56 (정수값이면 콤마 정수)
날짜/일시"2020-03-01 00:00:00" (datetime을 str()로 — ISO 변환 안 함)동일 문자열
불리언true/falseYes/No
수식계산 결과값 (data_only=True)계산 결과값
빈 셀null(공백)

JSON 셀 직렬화는 None/bool/int/float만 원형 유지하고 나머지(날짜·하이퍼링크 등)는 모두 str()로 변환합니다. 하이퍼링크/통화/퍼센트를 구조화 객체({value, format})로 분리하는 기능은 없습니다 — 셀의 텍스트/숫자 값만 출력됩니다.

병합 셀·멀티 헤더(그룹 헤더)는 자동 처리하지 않습니다. 현재 CLI는 iter_rows(values_only=True)로 첫 행을 단일 헤더로 사용합니다 — 병합 값 전파나 그룹 헤더 평탄화는 미지원입니다. 그런 시트는 위 Step 0로 구조를 먼저 확인하고 수동 보정하세요.


Step 2: 이미지 추출

xlsx는 ZIP 아카이브이며, 내부 XML을 파싱하여 이미지를 추출합니다:

  1. xl/worksheets/_rels/sheet*.xml.rels → 시트→드로잉 매핑
  2. xl/drawings/_rels/drawing*.xml.rels → rId→미디어 파일 매핑
  3. xl/drawings/drawing*.xml → 앵커에서 row/col + rId 추출
  4. xl/media/* → 이미지 바이너리 추출

Fallback: 드로잉 매핑 실패 시 media 폴더 전체 추출 (위치 없음 → "기타" 섹션 배치).


Step 3: 출력

JSON 구조

{
  "source": "report.xlsx",
  "sheet": "Sheet1",
  "row_count": 150,
  "headers": ["번호", "이름", "부서", "직급", "입사일"],
  "rows": [
    {"번호": 1, "이름": "김철수", "부서": "개발팀", "직급": "대리", "입사일": "2020-03-01 00:00:00"}
  ],
  "images": [
    {"filename": "image1.png", "row": 1, "col": 0}
  ]
}

Markdown 구조

# Sheet1

> Source: report.xlsx | Sheet: Sheet1 | Rows: 150 | Images: 5

| 번호 | 이름 | 부서 | 직급 | 입사일 |
|------|------|------|------|--------|
| 1 | 김철수 | 개발팀 | 대리 | 2020-03-01 00:00:00 |

## 첨부 이미지

### 행 1
![image1.png](image1.png)

특수 케이스 처리

케이스처리
파이프(|) 포함 셀MD에서만 이스케이프
시트명 특수문자안전한 파일명으로 변환 (/_)
이미지 없는 xlsx텍스트만 변환
twoCellAnchor + oneCellAnchor두 앵커 타입 모두 지원
빈 시트_(빈 시트)_ 표기

요구사항

pip install openpyxl

옵션

옵션단축설명
--formatjson(기본) 또는 md
--sheet-s특정 시트만
--output-o출력 디렉토리
--overwrite-f덮어쓰기
--no-images이미지 제외

Helper Scripts

스크립트용도
excel2md.py메인 CLI
scripts/excel_parser.pyopenpyxl 파싱 헬퍼

Related Files

파일역할
skills/pdf/SKILL.mdPDF 변환
skills/docx/SKILL.mdWord 문서 변환
skills/web-to-markdown/SKILL.md웹페이지 변환

Gives 0 of the 12 instructions most pdf office docs skills give in ~2.1k tokens

Counted across 635 of the 690 authors here whose files we hold, read 2026-08-06

  • extract text using pdfplumberin 92 of 635, across 25 files
  • create PDFs using reportlabin 83 of 635, across 16 files
  • read FORMS.md to fill out PDF formsin 80 of 635, across 13 files
  • OCR scanned PDFs using pytesseractin 77 of 635, across 10 files
  • merge or split PDFs using qpdfin 70 of 635, across 3 files
  • use Excel formulas instead of hardcoded calculated valuesin 68 of 635, across 12 files
  • unpack edit xml and repack existing documentsin 63 of 635, across 8 files
  • document sources for hardcoded valuesin 61 of 635, across 9 files
  • write minimal python code without unnecessary commentsin 59 of 635, across 7 files
  • run the recalculation script after adding or modifying formulasin 58 of 635, across 6 files
  • fix all identified formula errors and recalculatein 58 of 635, across 6 files
  • format years as text stringsin 57 of 635, across 5 files

Said here and by no other author read

  • Analyze workbook structure before conversion
  • Detect headers using string ratio in first rows
  • Use data_only to read formula calculation results
  • Serialize dates and hyperlinks using str()
  • Escape pipes and line breaks in markdown output
  • Extract embedded images and map them to rows

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.