[{"data":1,"prerenderedAt":1208},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fread-cell-value-from-excel-with-openpyxl":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fread-cell-value-from-excel-with-openpyxl":1199},{"id":4,"title":5,"body":6,"dateModified":1178,"datePublished":1178,"description":1179,"extension":1180,"faq":1181,"meta":1190,"navigation":238,"path":1191,"seo":1192,"slug":1195,"stem":1196,"type":1197,"__hash__":1198},"docs\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fread-cell-value-from-excel-with-openpyxl\u002Findex.md","Read a Cell Value From Excel With openpyxl",{"type":7,"value":8,"toc":1164},"minimark",[9,28,168,173,176,200,204,210,409,413,424,491,507,511,528,597,601,611,692,707,711,717,802,806,820,907,924,928,1044,1053,1057,1066,1070,1080,1093,1112,1118,1122,1140,1144,1160],[10,11,12,13,18,19,23,24,27],"p",{},"When you need the value of one cell — or a precise rectangle of cells — rather than a whole DataFrame, openpyxl is the direct tool. It opens a workbook, exposes every cell by coordinate, and lets you choose between a formula's text and its cached result. This guide, part of ",[14,15,17],"a",{"href":16},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002F","Using openpyxl for Excel File Manipulation",", walks through ",[20,21,22],"code",{},"load_workbook",", both cell-access styles, iterating rows, reading a range, and the ",[20,25,26],{},"data_only"," flag — with every snippet building its own sample file.",[29,30,38,39,38,43,38,47,38,54,38,58,38,62,38,67,38,71,38,75,38,84,38,87,38,90,38,93,38,98,38,100,38,103,38,105,38,109,38,115,38,121,38,126,38,131,38,135,38,142,38,146,38,153,38,159,38,164],"svg",{"viewBox":31,"role":32,"ariaLabelledBy":33,"xmlns":36,"style":37},"0 0 760 300","img",[34,35],"readc-t","readc-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:760px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[40,41,42],"title",{"id":34},"Addressing cells in an A1:C3 grid with openpyxl",[44,45,46],"desc",{"id":35},"A three-by-three grid shows columns A, B, C and rows 1 to 3; the cell B2 can be read with ws[\"B2\"] or ws.cell(row=2, column=2), and data_only=True returns the cached result of a formula instead of its text.",[48,49,53],"text",{"x":50,"y":51,"style":52},"48","64","font-size:13px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[48,55,57],{"x":56,"y":51,"style":52},"158","B",[48,59,61],{"x":60,"y":51,"style":52},"268","C",[48,63,66],{"x":64,"y":65,"style":52},"14","106","1",[48,68,70],{"x":64,"y":69,"style":52},"166","2",[48,72,74],{"x":64,"y":73,"style":52},"226","3",[76,77],"rect",{"x":78,"y":79,"width":80,"height":50,"rx":81,"fill":82,"stroke":83},"28","80","100","6","var(--surface-muted,#eef2ff)","var(--line,#cdd5e6)",[76,85],{"x":86,"y":79,"width":80,"height":50,"rx":81,"fill":82,"stroke":83},"138",[76,88],{"x":89,"y":79,"width":80,"height":50,"rx":81,"fill":82,"stroke":83},"248",[76,91],{"x":78,"y":92,"width":80,"height":50,"rx":81,"fill":82,"stroke":83},"140",[76,94],{"x":86,"y":92,"width":80,"height":50,"rx":81,"fill":95,"stroke":96,"style":97},"var(--brand,#5b5cf0)","var(--brand-strong,#4338ca)","stroke-width:2px",[76,99],{"x":89,"y":92,"width":80,"height":50,"rx":81,"fill":82,"stroke":83},[76,101],{"x":78,"y":102,"width":80,"height":50,"rx":81,"fill":82,"stroke":83},"200",[76,104],{"x":86,"y":102,"width":80,"height":50,"rx":81,"fill":82,"stroke":83},[76,106],{"x":89,"y":102,"width":80,"height":50,"rx":81,"fill":107,"stroke":108,"style":97},"rgba(15,148,136,0.14)","var(--teal,#0f9488)",[48,110,114],{"x":111,"y":112,"style":113},"188","170","font-size:15px;font-weight:700;fill:#ffffff;text-anchor:middle","B2",[48,116,120],{"x":117,"y":118,"style":119},"298","222","font-size:12.5px;font-weight:600;fill:var(--teal,#0f9488);text-anchor:middle","=SUM()",[48,122,125],{"x":123,"y":80,"style":124},"430","font-size:13px;font-weight:600;fill:var(--muted,#5b6780)","Two ways to reach B2",[48,127,130],{"x":123,"y":128,"style":129},"128","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca)","ws[\"B2\"].value",[48,132,134],{"x":123,"y":133,"style":129},"156","ws.cell(row=2, column=2)",[136,137],"line",{"x1":138,"y1":139,"x2":140,"y2":141,"stroke":95,"style":97},"240","164","424","142",[143,144],"polygon",{"points":145,"fill":95},"240,164 252,160 250,171",[76,147],{"x":123,"y":148,"width":149,"height":150,"rx":151,"fill":152,"stroke":108},"190","306","68","12","rgba(15,148,136,0.1)",[48,154,158],{"x":155,"y":156,"style":157},"448","216","font-size:13px;font-weight:700;fill:var(--teal,#0f9488)","data_only=True",[48,160,163],{"x":155,"y":161,"style":162},"238","font-size:12.5px;fill:var(--muted,#5b6780)","returns the cached result,",[48,165,167],{"x":155,"y":166,"style":162},"254","not the formula text",[169,170,172],"h2",{"id":171},"prerequisites","Prerequisites",[10,174,175],{},"Install openpyxl:",[177,178,183],"pre",{"className":179,"code":180,"language":181,"meta":182,"style":182},"language-bash shiki shiki-themes github-light github-dark","pip install openpyxl\n","bash","",[20,184,185],{"__ignoreMap":182},[186,187,189,193,197],"span",{"class":136,"line":188},1,[186,190,192],{"class":191},"sScJk","pip",[186,194,196],{"class":195},"sZZnC"," install",[186,198,199],{"class":195}," openpyxl\n",[169,201,203],{"id":202},"create-a-sample-workbook","Create a sample workbook",[10,205,206,207,209],{},"These examples read this file. It includes a formula in column C so the ",[20,208,26],{}," section has something to demonstrate:",[177,211,215],{"className":212,"code":213,"language":214,"meta":182,"style":182},"language-python shiki shiki-themes github-light github-dark","from openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nws.title = \"Sales\"\nws[\"A1\"], ws[\"B1\"], ws[\"C1\"] = \"SKU\", \"Qty\", \"Total\"\nws[\"A2\"], ws[\"B2\"], ws[\"C2\"] = \"A-100\", 3, \"=B2*10\"\nws[\"A3\"], ws[\"B3\"], ws[\"C3\"] = \"B-200\", 5, \"=B3*10\"\nwb.save(\"sales.xlsx\")\nprint(\"wrote sales.xlsx\")\n","python",[20,216,217,233,240,252,263,274,313,348,383,395],{"__ignoreMap":182},[186,218,219,223,227,230],{"class":136,"line":188},[186,220,222],{"class":221},"szBVR","from",[186,224,226],{"class":225},"sVt8B"," openpyxl ",[186,228,229],{"class":221},"import",[186,231,232],{"class":225}," Workbook\n",[186,234,236],{"class":136,"line":235},2,[186,237,239],{"emptyLinePlaceholder":238},true,"\n",[186,241,243,246,249],{"class":136,"line":242},3,[186,244,245],{"class":225},"wb ",[186,247,248],{"class":221},"=",[186,250,251],{"class":225}," Workbook()\n",[186,253,255,258,260],{"class":136,"line":254},4,[186,256,257],{"class":225},"ws ",[186,259,248],{"class":221},[186,261,262],{"class":225}," wb.active\n",[186,264,266,269,271],{"class":136,"line":265},5,[186,267,268],{"class":225},"ws.title ",[186,270,248],{"class":221},[186,272,273],{"class":195}," \"Sales\"\n",[186,275,277,280,283,286,289,291,294,297,299,302,305,308,310],{"class":136,"line":276},6,[186,278,279],{"class":225},"ws[",[186,281,282],{"class":195},"\"A1\"",[186,284,285],{"class":225},"], ws[",[186,287,288],{"class":195},"\"B1\"",[186,290,285],{"class":225},[186,292,293],{"class":195},"\"C1\"",[186,295,296],{"class":225},"] ",[186,298,248],{"class":221},[186,300,301],{"class":195}," \"SKU\"",[186,303,304],{"class":225},", ",[186,306,307],{"class":195},"\"Qty\"",[186,309,304],{"class":225},[186,311,312],{"class":195},"\"Total\"\n",[186,314,316,318,321,323,326,328,331,333,335,338,340,343,345],{"class":136,"line":315},7,[186,317,279],{"class":225},[186,319,320],{"class":195},"\"A2\"",[186,322,285],{"class":225},[186,324,325],{"class":195},"\"B2\"",[186,327,285],{"class":225},[186,329,330],{"class":195},"\"C2\"",[186,332,296],{"class":225},[186,334,248],{"class":221},[186,336,337],{"class":195}," \"A-100\"",[186,339,304],{"class":225},[186,341,74],{"class":342},"sj4cs",[186,344,304],{"class":225},[186,346,347],{"class":195},"\"=B2*10\"\n",[186,349,351,353,356,358,361,363,366,368,370,373,375,378,380],{"class":136,"line":350},8,[186,352,279],{"class":225},[186,354,355],{"class":195},"\"A3\"",[186,357,285],{"class":225},[186,359,360],{"class":195},"\"B3\"",[186,362,285],{"class":225},[186,364,365],{"class":195},"\"C3\"",[186,367,296],{"class":225},[186,369,248],{"class":221},[186,371,372],{"class":195}," \"B-200\"",[186,374,304],{"class":225},[186,376,377],{"class":342},"5",[186,379,304],{"class":225},[186,381,382],{"class":195},"\"=B3*10\"\n",[186,384,386,389,392],{"class":136,"line":385},9,[186,387,388],{"class":225},"wb.save(",[186,390,391],{"class":195},"\"sales.xlsx\"",[186,393,394],{"class":225},")\n",[186,396,398,401,404,407],{"class":136,"line":397},10,[186,399,400],{"class":342},"print",[186,402,403],{"class":225},"(",[186,405,406],{"class":195},"\"wrote sales.xlsx\"",[186,408,394],{"class":225},[169,410,412],{"id":411},"read-one-cell-by-coordinate","Read one cell by coordinate",[10,414,415,416,419,420,423],{},"Load the workbook, pick a worksheet, and read ",[20,417,418],{},".value",". The ",[20,421,422],{},"[\"B2\"]"," syntax mirrors the spreadsheet UI:",[177,425,427],{"className":212,"code":426,"language":214,"meta":182,"style":182},"from openpyxl import load_workbook\n\nwb = load_workbook(\"sales.xlsx\")\nws = wb[\"Sales\"]                 # or wb.active for the first sheet\nprint(ws[\"B2\"].value)            # -> 3\n",[20,428,429,440,444,457,476],{"__ignoreMap":182},[186,430,431,433,435,437],{"class":136,"line":188},[186,432,222],{"class":221},[186,434,226],{"class":225},[186,436,229],{"class":221},[186,438,439],{"class":225}," load_workbook\n",[186,441,442],{"class":136,"line":235},[186,443,239],{"emptyLinePlaceholder":238},[186,445,446,448,450,453,455],{"class":136,"line":242},[186,447,245],{"class":225},[186,449,248],{"class":221},[186,451,452],{"class":225}," load_workbook(",[186,454,391],{"class":195},[186,456,394],{"class":225},[186,458,459,461,463,466,469,472],{"class":136,"line":254},[186,460,257],{"class":225},[186,462,248],{"class":221},[186,464,465],{"class":225}," wb[",[186,467,468],{"class":195},"\"Sales\"",[186,470,471],{"class":225},"]                 ",[186,473,475],{"class":474},"sJ8bj","# or wb.active for the first sheet\n",[186,477,478,480,483,485,488],{"class":136,"line":265},[186,479,400],{"class":342},[186,481,482],{"class":225},"(ws[",[186,484,325],{"class":195},[186,486,487],{"class":225},"].value)            ",[186,489,490],{"class":474},"# -> 3\n",[10,492,493,496,497,500,501,503,504,506],{},[20,494,495],{},"ws[\"B2\"]"," returns a ",[20,498,499],{},"Cell"," object; the data lives on its ",[20,502,418],{}," attribute. Forgetting ",[20,505,418],{}," gives you the cell wrapper, not the number.",[169,508,510],{"id":509},"read-a-cell-by-row-and-column-number","Read a cell by row and column number",[10,512,513,515,516,520,521,524,525,527],{},[20,514,134],{}," reaches the same cell numerically — the form you want inside loops or when coordinates are computed. openpyxl is ",[517,518,519],"strong",{},"1-based",": row 1 and column 1 are the top-left cell, so ",[20,522,523],{},"row=2, column=2"," is ",[20,526,114],{},":",[177,529,531],{"className":212,"code":530,"language":214,"meta":182,"style":182},"from openpyxl import load_workbook\n\nwb = load_workbook(\"sales.xlsx\")\nws = wb.active\nprint(ws.cell(row=2, column=2).value)   # -> 3, same cell as B2\n",[20,532,533,543,547,559,567],{"__ignoreMap":182},[186,534,535,537,539,541],{"class":136,"line":188},[186,536,222],{"class":221},[186,538,226],{"class":225},[186,540,229],{"class":221},[186,542,439],{"class":225},[186,544,545],{"class":136,"line":235},[186,546,239],{"emptyLinePlaceholder":238},[186,548,549,551,553,555,557],{"class":136,"line":242},[186,550,245],{"class":225},[186,552,248],{"class":221},[186,554,452],{"class":225},[186,556,391],{"class":195},[186,558,394],{"class":225},[186,560,561,563,565],{"class":136,"line":254},[186,562,257],{"class":225},[186,564,248],{"class":221},[186,566,262],{"class":225},[186,568,569,571,574,578,580,582,584,587,589,591,594],{"class":136,"line":265},[186,570,400],{"class":342},[186,572,573],{"class":225},"(ws.cell(",[186,575,577],{"class":576},"s4XuR","row",[186,579,248],{"class":221},[186,581,70],{"class":342},[186,583,304],{"class":225},[186,585,586],{"class":576},"column",[186,588,248],{"class":221},[186,590,70],{"class":342},[186,592,593],{"class":225},").value)   ",[186,595,596],{"class":474},"# -> 3, same cell as B2\n",[169,598,600],{"id":599},"iterate-rows-with-values-only","Iterate rows with values only",[10,602,603,604,607,608,610],{},"To sweep a sheet, ",[20,605,606],{},"iter_rows(values_only=True)"," yields plain tuples of values instead of ",[20,609,499],{}," objects — less overhead and easier to unpack:",[177,612,614],{"className":212,"code":613,"language":214,"meta":182,"style":182},"from openpyxl import load_workbook\n\nwb = load_workbook(\"sales.xlsx\")\nws = wb.active\nfor sku, qty, total in ws.iter_rows(min_row=2, values_only=True):\n    print(sku, qty, total)\n",[20,615,616,626,630,642,650,684],{"__ignoreMap":182},[186,617,618,620,622,624],{"class":136,"line":188},[186,619,222],{"class":221},[186,621,226],{"class":225},[186,623,229],{"class":221},[186,625,439],{"class":225},[186,627,628],{"class":136,"line":235},[186,629,239],{"emptyLinePlaceholder":238},[186,631,632,634,636,638,640],{"class":136,"line":242},[186,633,245],{"class":225},[186,635,248],{"class":221},[186,637,452],{"class":225},[186,639,391],{"class":195},[186,641,394],{"class":225},[186,643,644,646,648],{"class":136,"line":254},[186,645,257],{"class":225},[186,647,248],{"class":221},[186,649,262],{"class":225},[186,651,652,655,658,661,664,667,669,671,673,676,678,681],{"class":136,"line":265},[186,653,654],{"class":221},"for",[186,656,657],{"class":225}," sku, qty, total ",[186,659,660],{"class":221},"in",[186,662,663],{"class":225}," ws.iter_rows(",[186,665,666],{"class":576},"min_row",[186,668,248],{"class":221},[186,670,70],{"class":342},[186,672,304],{"class":225},[186,674,675],{"class":576},"values_only",[186,677,248],{"class":221},[186,679,680],{"class":342},"True",[186,682,683],{"class":225},"):\n",[186,685,686,689],{"class":136,"line":276},[186,687,688],{"class":342},"    print",[186,690,691],{"class":225},"(sku, qty, total)\n",[10,693,694,695,698,699,702,703,706],{},"Drop ",[20,696,697],{},"min_row=2"," to include the header row. Use ",[20,700,701],{},"min_col","\u002F",[20,704,705],{},"max_col"," to bound the columns you read.",[169,708,710],{"id":709},"read-a-rectangular-range","Read a rectangular range",[10,712,713,714,716],{},"Index the worksheet with a range string to get a tuple of rows, each a tuple of cells. Pull ",[20,715,418],{}," from each to flatten it:",[177,718,720],{"className":212,"code":719,"language":214,"meta":182,"style":182},"from openpyxl import load_workbook\n\nwb = load_workbook(\"sales.xlsx\")\nws = wb.active\nvalues = [[cell.value for cell in row] for row in ws[\"A1:B3\"]]\nprint(values)   # [['SKU', 'Qty'], ['A-100', 3], ['B-200', 5]]\n",[20,721,722,732,736,748,756,792],{"__ignoreMap":182},[186,723,724,726,728,730],{"class":136,"line":188},[186,725,222],{"class":221},[186,727,226],{"class":225},[186,729,229],{"class":221},[186,731,439],{"class":225},[186,733,734],{"class":136,"line":235},[186,735,239],{"emptyLinePlaceholder":238},[186,737,738,740,742,744,746],{"class":136,"line":242},[186,739,245],{"class":225},[186,741,248],{"class":221},[186,743,452],{"class":225},[186,745,391],{"class":195},[186,747,394],{"class":225},[186,749,750,752,754],{"class":136,"line":254},[186,751,257],{"class":225},[186,753,248],{"class":221},[186,755,262],{"class":225},[186,757,758,761,763,766,768,771,773,776,778,781,783,786,789],{"class":136,"line":265},[186,759,760],{"class":225},"values ",[186,762,248],{"class":221},[186,764,765],{"class":225}," [[cell.value ",[186,767,654],{"class":221},[186,769,770],{"class":225}," cell ",[186,772,660],{"class":221},[186,774,775],{"class":225}," row] ",[186,777,654],{"class":221},[186,779,780],{"class":225}," row ",[186,782,660],{"class":221},[186,784,785],{"class":225}," ws[",[186,787,788],{"class":195},"\"A1:B3\"",[186,790,791],{"class":225},"]]\n",[186,793,794,796,799],{"class":136,"line":276},[186,795,400],{"class":342},[186,797,798],{"class":225},"(values)   ",[186,800,801],{"class":474},"# [['SKU', 'Qty'], ['A-100', 3], ['B-200', 5]]\n",[169,803,805],{"id":804},"formula-text-vs-cached-result-with-data_only","Formula text vs. cached result with data_only",[10,807,808,809,812,813,815,816,819],{},"By default openpyxl returns the ",[517,810,811],{},"formula string"," for a calculated cell. Pass ",[20,814,158],{}," to get the ",[517,817,818],{},"cached result"," Excel last computed and stored in the file instead:",[177,821,823],{"className":212,"code":822,"language":214,"meta":182,"style":182},"from openpyxl import load_workbook\n\nformula = load_workbook(\"sales.xlsx\")\nprint(formula.active[\"C2\"].value)             # -> '=B2*10' (the formula text)\n\ncached = load_workbook(\"sales.xlsx\", data_only=True)\nprint(cached.active[\"C2\"].value)              # -> None until Excel saved a result\n",[20,824,825,835,839,852,867,871,892],{"__ignoreMap":182},[186,826,827,829,831,833],{"class":136,"line":188},[186,828,222],{"class":221},[186,830,226],{"class":225},[186,832,229],{"class":221},[186,834,439],{"class":225},[186,836,837],{"class":136,"line":235},[186,838,239],{"emptyLinePlaceholder":238},[186,840,841,844,846,848,850],{"class":136,"line":242},[186,842,843],{"class":225},"formula ",[186,845,248],{"class":221},[186,847,452],{"class":225},[186,849,391],{"class":195},[186,851,394],{"class":225},[186,853,854,856,859,861,864],{"class":136,"line":254},[186,855,400],{"class":342},[186,857,858],{"class":225},"(formula.active[",[186,860,330],{"class":195},[186,862,863],{"class":225},"].value)             ",[186,865,866],{"class":474},"# -> '=B2*10' (the formula text)\n",[186,868,869],{"class":136,"line":265},[186,870,239],{"emptyLinePlaceholder":238},[186,872,873,876,878,880,882,884,886,888,890],{"class":136,"line":276},[186,874,875],{"class":225},"cached ",[186,877,248],{"class":221},[186,879,452],{"class":225},[186,881,391],{"class":195},[186,883,304],{"class":225},[186,885,26],{"class":576},[186,887,248],{"class":221},[186,889,680],{"class":342},[186,891,394],{"class":225},[186,893,894,896,899,901,904],{"class":136,"line":315},[186,895,400],{"class":342},[186,897,898],{"class":225},"(cached.active[",[186,900,330],{"class":195},[186,902,903],{"class":225},"].value)              ",[186,905,906],{"class":474},"# -> None until Excel saved a result\n",[10,908,909,910,912,913,916,917,919,920,923],{},"The catch: openpyxl never evaluates formulas itself. ",[20,911,158],{}," only returns a value if a real spreadsheet application — Excel, LibreOffice, or similar — opened the file, recalculated, and saved the cached results. A workbook that openpyxl created and saved (like our ",[20,914,915],{},"sales.xlsx",") has no cached values, so ",[20,918,158],{}," returns ",[20,921,922],{},"None"," for every formula cell. Open and resave the file in Excel once, and the cached results appear.",[169,925,927],{"id":926},"common-pitfalls","Common pitfalls",[929,930,931,947],"table",{},[932,933,934],"thead",{},[935,936,937,941,944],"tr",{},[938,939,940],"th",{},"Symptom",[938,942,943],{},"Cause",[938,945,946],{},"Fix",[948,949,950,971,991,1005,1026],"tbody",{},[935,951,952,960,963],{},[953,954,955,956,959],"td",{},"Got a ",[20,957,958],{},"\u003CCell>"," repr, not the value",[953,961,962],{},"Read the cell object, not its data",[953,964,965,966,968,969],{},"Append ",[20,967,418],{},": ",[20,970,130],{},[935,972,973,982,985],{},[953,974,975,978,979],{},[20,976,977],{},"IndexError"," or wrong cell with ",[20,980,981],{},"cell()",[953,983,984],{},"Used 0-based indices",[953,986,987,988],{},"openpyxl is 1-based; top-left is ",[20,989,990],{},"row=1, column=1",[935,992,993,999,1002],{},[953,994,995,919,997],{},[20,996,158],{},[20,998,922],{},[953,1000,1001],{},"File has no cached formula results",[953,1003,1004],{},"Open and save the file in Excel first; openpyxl won't compute",[935,1006,1007,1013,1016],{},[953,1008,1009,1012],{},[20,1010,1011],{},"MemoryError"," on a huge file",[953,1014,1015],{},"Loaded the whole workbook into RAM",[953,1017,1018,1019,1022,1023],{},"Use ",[20,1020,1021],{},"load_workbook(path, read_only=True)"," and stream ",[20,1024,1025],{},"iter_rows",[935,1027,1028,1034,1039],{},[953,1029,1030,1031],{},"Edits don't stick after ",[20,1032,1033],{},"read_only",[953,1035,1036,1038],{},[20,1037,1033],{}," mode is non-writable",[953,1040,694,1041,1043],{},[20,1042,1033],{}," when you need to modify cells",[10,1045,1046,1047,1049,1050,1052],{},"A second subtlety: you can't have both the formula text and the cached result from one ",[20,1048,22],{}," call. Open the file twice — once plain, once with ",[20,1051,158],{}," — if you need both.",[169,1054,1056],{"id":1055},"performance-and-scale","Performance and scale",[10,1058,1059,1060,1062,1063,1065],{},"For large workbooks where you only read, ",[20,1061,1021],{}," switches openpyxl to a streaming parser that loads rows lazily, keeping memory flat as the file grows. It pairs naturally with ",[20,1064,606],{},". Note that read-only mode disables writing and some cell attributes, so use it only for pure extraction.",[169,1067,1069],{"id":1068},"frequently-asked-questions","Frequently asked questions",[10,1071,1072,1075,1076,1079],{},[517,1073,1074],{},"Why does my cell return the formula string instead of the number?","\nThat's the default. Reload with ",[20,1077,1078],{},"load_workbook(path, data_only=True)"," to get the cached result — provided Excel computed and saved it.",[10,1081,1082,1085,1086,524,1089,1092],{},[517,1083,1084],{},"Is openpyxl 0-based or 1-based?","\n1-based, everywhere. ",[20,1087,1088],{},"ws.cell(row=1, column=1)",[20,1090,1091],{},"A1",". This matches the spreadsheet UI but differs from Python list indexing.",[10,1094,1095,1098,1099,1101,1102,1104,1105,1108,1109,1111],{},[517,1096,1097],{},"How do I read just the value, not the cell object?","\nAlways go through ",[20,1100,418],{}," — ",[20,1103,130],{}," or ",[20,1106,1107],{},"ws.cell(row=2, column=2).value",". ",[20,1110,606],{}," does this for you across a whole sweep.",[10,1113,1114,1117],{},[517,1115,1116],{},"Can openpyxl calculate formulas for me?","\nNo. It reads formula text or the cached result, but never evaluates. For live computation, use a tool that drives Excel itself, such as xlwings.",[169,1119,1121],{"id":1120},"conclusion","Conclusion",[10,1123,1124,1125,1127,1128,1130,1131,1133,1134,1136,1137,1139],{},"openpyxl gives you two equivalent ways to reach a cell — ",[20,1126,130],{}," for readability and ",[20,1129,1107],{}," for computed coordinates — both 1-based. To sweep a sheet, ",[20,1132,606],{}," is fastest; to scope a region, index with a range string. The one rule to remember about formulas: openpyxl doesn't calculate, so ",[20,1135,158],{}," returns the cached result only when a spreadsheet app saved one, and ",[20,1138,922],{}," otherwise.",[169,1141,1143],{"id":1142},"where-to-go-next","Where to go next",[10,1145,1146,1147,1149,1150,1154,1155,1159],{},"Return to ",[14,1148,17],{"href":16}," for the broader read-and-edit workflow. To write back to a file you've opened, see ",[14,1151,1153],{"href":1152},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fopenpyxl-append-data-to-existing-excel-sheet\u002F","Append Data to an Existing Excel Sheet with openpyxl",". For when to use openpyxl versus a faster write-only engine, read ",[14,1156,1158],{"href":1157},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fopenpyxl-vs-xlsxwriter-vs-pandas-excelwriter\u002F","openpyxl vs xlsxwriter vs pandas.ExcelWriter",".",[1161,1162,1163],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":182,"searchDepth":235,"depth":235,"links":1165},[1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177],{"id":171,"depth":235,"text":172},{"id":202,"depth":235,"text":203},{"id":411,"depth":235,"text":412},{"id":509,"depth":235,"text":510},{"id":599,"depth":235,"text":600},{"id":709,"depth":235,"text":710},{"id":804,"depth":235,"text":805},{"id":926,"depth":235,"text":927},{"id":1055,"depth":235,"text":1056},{"id":1068,"depth":235,"text":1069},{"id":1120,"depth":235,"text":1121},{"id":1142,"depth":235,"text":1143},"2026-06-18","Read Excel cell values with openpyxl: load_workbook, ws['B2'].value, ws.cell(), iter_rows, ranges, and data_only for cached formula results instead of formula text.","md",[1182,1184,1186,1188],{"q":1074,"a":1183},"That's the default. Reload with load_workbook(path, data_only=True) to get the cached result — provided Excel computed and saved it.",{"q":1084,"a":1185},"1-based, everywhere. ws.cell(row=1, column=1) is A1. This matches the spreadsheet UI but differs from Python list indexing.",{"q":1097,"a":1187},"Always go through .value — ws[\"B2\"].value or ws.cell(row=2, column=2).value. iter_rows(values_only=True) does this for you across a whole sweep.",{"q":1116,"a":1189},"No. It reads formula text or the cached result, but never evaluates. For live computation, use a tool that drives Excel itself, such as xlwings.",{},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fread-cell-value-from-excel-with-openpyxl",{"title":1193,"description":1194},"Read a Cell Value from Excel with openpyxl","Get cell values in openpyxl via ws['B2'].value and ws.cell(row, column), iterate rows, read ranges, and use data_only to pull cached formula results over formula strings.","read-cell-value-from-excel-with-openpyxl","getting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fread-cell-value-from-excel-with-openpyxl\u002Findex","long_tail","EP3s1fjcFkpjwsEF2eJ8Q8cqUgVU2L2Cs6nVmSFgc0I",[1200,1204],{"title":1201,"path":1202,"stem":1203,"children":-1},"openpyxl: Append Data to an Existing Excel Sheet","\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fopenpyxl-append-data-to-existing-excel-sheet","getting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fopenpyxl-append-data-to-existing-excel-sheet\u002Findex",{"title":1205,"path":1206,"stem":1207,"children":-1},"Working with Multiple Excel Sheets in Python","\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python","getting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Findex",1781795518561]