π OpenPyXL
OpenPyXL is a Python library used to create, read, modify, and format Excel (.xlsx) files.
It is especially useful for automating Excel tasks.
π¦ Install
pip install openpyxlImport it:
import openpyxlπ Read an Excel File
import openpyxl
workbook = openpyxl.load_workbook("students.xlsx")
sheet = workbook.active
print(sheet["A1"].value)βοΈ Write Data
sheet["A1"] = "Name"
sheet["B1"] = "Age"
sheet["A2"] = "Tisha"
sheet["B2"] = 23
workbook.save("students.xlsx")π Create a New Excel File
import openpyxl
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet["A1"] = "Name"
sheet["A2"] = "Tisha"
workbook.save("students.xlsx")π§ Common OpenPyXL Functions
openpyxl.Workbook() # Create a new workbook
openpyxl.load_workbook() # Open an existing workbook
sheet["A1"].value # Read a cell
sheet["A1"] = "Hello" # Write to a cell
workbook.save("file.xlsx") # Save workbook<div class="infographic-pyopenpyxl">
<style>
.infographic-pyopenpyxl {
--ink:#1a1a1a; --ink-soft:#5c5c5c; --paper:#fff; --paper-alt:#f0ece4;
--accent:#2563eb; --accent-soft:#e3ebfd; --line:#ddd6c9;
--ok:#1f9d55; --ok-soft:#e3f5ec;
--mono-font:'IBM Plex Mono','SFMono-Regular',Menlo,monospace;
--display-font:'Fraunces',Georgia,serif; --body-font:'Inter',system-ui,sans-serif;
box-sizing:border-box; max-width:700px; margin:0 auto; font-family:var(--body-font); color:var(--ink); background:var(--paper);
}
.infographic-pyopenpyxl[data-theme="dark"] {
--ink:#e8e6e1; --ink-soft:#9a968c; --paper:#121212; --paper-alt:#1e1e26;
--accent:#5b8def; --accent-soft:#202942; --line:#2c313d;
--ok:#6fdc8c; --ok-soft:#16342a;
}
.infographic-pyopenpyxl *,.infographic-pyopenpyxl *::before,.infographic-pyopenpyxl *::after{box-sizing:border-box;}
.infographic-pyopenpyxl .ox-wrap{padding:0 clamp(1rem,4vw,2rem) 1.5rem;}
.infographic-pyopenpyxl h1{font-family:var(--display-font);font-weight:600;font-size:clamp(1.4rem,5vw,1.9rem);text-align:center;margin:1.5rem 0 0.25rem;letter-spacing:-0.01em;}
.infographic-pyopenpyxl .ox-sub{text-align:center;color:var(--ink-soft);font-size:0.85rem;margin:0 0 1.3rem;}
.infographic-pyopenpyxl .code-line{text-align:center;font-family:var(--mono-font);font-size:0.78rem;color:var(--ink-soft);margin-bottom:1rem;}
.infographic-pyopenpyxl .sheet-wrap{display:flex;justify-content:center;margin-bottom:1rem;overflow-x:auto;}
.infographic-pyopenpyxl table.sheet{border-collapse:collapse;font-family:var(--mono-font);font-size:0.78rem;}
.infographic-pyopenpyxl table.sheet th,.infographic-pyopenpyxl table.sheet td{border:1px solid var(--line);padding:0.35rem 0.6rem;text-align:center;min-width:70px;transition:background .3s,border-color .3s,color .3s;}
.infographic-pyopenpyxl table.sheet th{background:var(--paper-alt);color:var(--ink-soft);}
.infographic-pyopenpyxl table.sheet td.cell{cursor:pointer;}
.infographic-pyopenpyxl table.sheet td.cell.is-selected{border-color:var(--accent);background:var(--accent-soft);color:var(--accent);font-weight:700;}
.infographic-pyopenpyxl table.sheet td.cell.is-flash{animation:ox-flash .6s ease;}
@keyframes ox-flash{0%{background:var(--ok-soft);}100%{background:transparent;}}
.infographic-pyopenpyxl .row{display:flex;justify-content:center;gap:0.4rem;margin-bottom:0.9rem;flex-wrap:wrap;align-items:center;}
.infographic-pyopenpyxl .row span{font-family:var(--mono-font);font-size:0.8rem;color:var(--ink-soft);}
.infographic-pyopenpyxl .row input{font-family:var(--mono-font);font-size:0.82rem;padding:0.4rem 0.55rem;border:1.5px solid var(--line);border-radius:5px;background:var(--paper-alt);color:var(--ink);width:100px;text-align:center;}
.infographic-pyopenpyxl .row input:focus{outline:none;border-color:var(--accent);}
.infographic-pyopenpyxl .btn{font:inherit;font-family:var(--mono-font);font-size:0.8rem;font-weight:700;background:var(--accent);color:#fff;border:none;border-radius:999px;padding:0.42rem 0.9rem;cursor:pointer;}
.infographic-pyopenpyxl .btn.secondary{background:var(--paper-alt);color:var(--ink);border:1.5px solid var(--line);border-radius:6px;}
.infographic-pyopenpyxl .append-row input{width:80px;}
.infographic-pyopenpyxl .result-box{text-align:center;font-family:var(--mono-font);font-size:0.85rem;font-weight:700;color:var(--accent);min-height:1.4em;margin-bottom:0.6rem;}
.infographic-pyopenpyxl .ox-caption{text-align:center;font-size:0.85rem;color:var(--ink-soft);margin-top:0.6rem;}
@media (prefers-reduced-motion:reduce){.infographic-pyopenpyxl *,.infographic-pyopenpyxl *::before,.infographic-pyopenpyxl *::after{animation-duration:.001ms!important;transition-duration:.001ms!important;}}
</style>
<div class="ox-wrap">
<h1>OpenPyXL</h1>
<p class="ox-sub">Read, write, and append to a real Excel sheet β no Excel required.</p>
<div class="code-line">wb = openpyxl.load_workbook("data.xlsx") Β· ws = wb.active</div>
<div class="sheet-wrap"><div id="sheetTable"></div></div>
<div class="row">
<span>ws[</span><input id="cellRefInput" type="text" value="B2" style="width:60px;" /><span>]</span>
<button class="btn" id="readCellBtn">read .value</button>
</div>
<div class="row">
<span>ws[</span><input id="writeRefInput" type="text" value="B2" style="width:60px;" /><span>] =</span>
<input id="writeValInput" type="text" value="31" />
<button class="btn secondary" id="writeCellBtn">write</button>
</div>
<div class="row append-row">
<input id="appendA" type="text" value="Dara" placeholder="name" />
<input id="appendB" type="text" value="29" placeholder="age" />
<input id="appendC" type="text" value="NYC" placeholder="city" />
<button class="btn secondary" id="appendBtn">ws.append([...])</button>
</div>
<div class="row">
<button class="btn secondary" id="saveBtn">wb.save("data.xlsx")</button>
</div>
<p class="result-box" id="oxResult">Click a cell, or use the controls above.</p>
<p class="ox-caption">Click any cell in the sheet to select it β the read/write fields update to match.</p>
</div>
<script>
(function(){
var root = document.currentScript.closest('.infographic-pyopenpyxl') || document.querySelector('.infographic-pyopenpyxl');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark = bodyAttr === 'true' ? true : bodyAttr === 'false' ? false : (document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/) || [])[1] === 'true';
if (dark) root.setAttribute('data-theme', 'dark');
var cols = ['A', 'B', 'C'];
var headers = ['name', 'age', 'city'];
var sheetData = [
['Alice', '25', 'NYC'],
['Bob', '30', 'LA']
];
var sheetTable = root.querySelector('#sheetTable');
var cellRefInput = root.querySelector('#cellRefInput');
var writeRefInput = root.querySelector('#writeRefInput');
var writeValInput = root.querySelector('#writeValInput');
var resultEl = root.querySelector('#oxResult');
var selectedRef = 'B2';
function refToCoord(ref) {
var m = ref.trim().toUpperCase().match(/^([A-C])([1-9]\d*)$/);
if (!m) return null;
var col = cols.indexOf(m[1]);
var row = parseInt(m[2], 10) - 2; // row 1 = header
if (col === -1 || row < 0 || row >= sheetData.length) return null;
return { col: col, row: row };
}
function renderSheet() {
var table = document.createElement('table');
table.className = 'sheet';
var thead = document.createElement('tr');
thead.appendChild(document.createElement('th'));
cols.forEach(function (c) { var th = document.createElement('th'); th.textContent = c; thead.appendChild(th); });
table.appendChild(thead);
var hrow = document.createElement('tr');
var hcell = document.createElement('th'); hcell.textContent = '1'; hrow.appendChild(hcell);
headers.forEach(function (h) { var th = document.createElement('th'); th.textContent = h; hrow.appendChild(th); });
table.appendChild(hrow);
sheetData.forEach(function (row, r) {
var tr = document.createElement('tr');
var rowLabel = document.createElement('th'); rowLabel.textContent = String(r + 2); tr.appendChild(rowLabel);
row.forEach(function (val, c) {
var td = document.createElement('td');
td.className = 'cell';
var ref = cols[c] + (r + 2);
td.dataset.ref = ref;
td.textContent = val;
if (ref === selectedRef) td.classList.add('is-selected');
td.addEventListener('click', function () {
selectedRef = ref;
cellRefInput.value = ref;
writeRefInput.value = ref;
writeValInput.value = val;
renderSheet();
resultEl.textContent = 'Selected ws["' + ref + '"]';
});
tr.appendChild(td);
});
table.appendChild(tr);
});
sheetTable.innerHTML = '';
sheetTable.appendChild(table);
}
root.querySelector('#readCellBtn').addEventListener('click', function () {
var ref = cellRefInput.value.trim().toUpperCase();
var coord = refToCoord(ref);
if (!coord) { resultEl.textContent = 'ws["' + ref + '"].value β None (empty or out of range)'; return; }
resultEl.textContent = 'ws["' + ref + '"].value β "' + sheetData[coord.row][coord.col] + '"';
});
root.querySelector('#writeCellBtn').addEventListener('click', function () {
var ref = writeRefInput.value.trim().toUpperCase();
var coord = refToCoord(ref);
var val = writeValInput.value;
if (!coord) { resultEl.textContent = 'Cell "' + ref + '" is out of range.'; return; }
sheetData[coord.row][coord.col] = val;
selectedRef = ref;
renderSheet();
var cellEl = sheetTable.querySelector('[data-ref="' + ref + '"]');
if (cellEl) { cellEl.classList.add('is-flash'); setTimeout(function () { cellEl.classList.remove('is-flash'); }, 600); }
resultEl.textContent = 'ws["' + ref + '"] = "' + val + '" β cell updated';
});
root.querySelector('#appendBtn').addEventListener('click', function () {
var a = root.querySelector('#appendA').value.trim() || 'Name';
var b = root.querySelector('#appendB').value.trim() || '0';
var c = root.querySelector('#appendC').value.trim() || 'City';
sheetData.push([a, b, c]);
renderSheet();
var newRowNum = sheetData.length + 1;
var cellEl = sheetTable.querySelector('[data-ref="A' + newRowNum + '"]');
if (cellEl) { cellEl.classList.add('is-flash'); setTimeout(function () { cellEl.classList.remove('is-flash'); }, 600); }
resultEl.textContent = 'ws.append(["' + a + '", "' + b + '", "' + c + '"]) β new row ' + newRowNum + ' added';
});
root.querySelector('#saveBtn').addEventListener('click', function () {
resultEl.textContent = 'wb.save("data.xlsx") β all changes above are now written to disk';
});
renderSheet();
})();
</script>
</div>