[{"data":1,"prerenderedAt":1049},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel\u002Fadd-logo-image-to-excel-report-with-openpyxl":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel\u002Fadd-logo-image-to-excel-report-with-openpyxl":1041},{"id":4,"title":5,"body":6,"description":1032,"extension":1033,"meta":1034,"navigation":106,"path":1035,"seo":1036,"stem":1039,"__hash__":1040},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel\u002Fadd-logo-image-to-excel-report-with-openpyxl\u002Findex.md","Add a Logo Image to an Excel Report with openpyxl",{"type":7,"value":8,"toc":1020},"minimark",[9,19,24,32,61,64,68,71,165,169,180,271,275,290,502,506,509,646,650,661,769,776,780,894,908,916,920,932,938,949,962,971,975,981,985,988,997,1000,1016],[10,11,12,13,18],"p",{},"You have a report and you want your logo in the top-left corner. This page is the copy-paste recipe: create the image, anchor it at A1, size it to fit a header band, set a merged title next to it, and save — with every pitfall that bites people on the way. It is the hands-on companion to ",[14,15,17],"a",{"href":16},"\u002Fformatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel\u002F","Inserting Images and Logos into Excel",", which covers the concepts; here we just build the thing.",[20,21,23],"h2",{"id":22},"prerequisites","Prerequisites",[10,25,26,27,31],{},"You need two libraries. openpyxl writes the workbook and its drawing XML; ",[28,29,30],"strong",{},"Pillow"," is what openpyxl uses to read and measure the image, so the logo step fails without it.",[33,34,39],"pre",{"className":35,"code":36,"language":37,"meta":38,"style":38},"language-bash shiki shiki-themes github-light github-dark","pip install openpyxl pillow\n","bash","",[40,41,42],"code",{"__ignoreMap":38},[43,44,47,51,55,58],"span",{"class":45,"line":46},"line",1,[43,48,50],{"class":49},"sScJk","pip",[43,52,54],{"class":53},"sZZnC"," install",[43,56,57],{"class":53}," openpyxl",[43,59,60],{"class":53}," pillow\n",[10,62,63],{},"No Excel install is required — this runs unchanged on a server or CI runner.",[20,65,67],{"id":66},"step-1-create-a-sample-logo","Step 1: create a sample logo",[10,69,70],{},"So this guide runs end to end with nothing to download, generate a small placeholder PNG with Pillow. In your real report, skip this and point at your actual logo file.",[33,72,76],{"className":73,"code":74,"language":75,"meta":38,"style":38},"language-python shiki shiki-themes github-light github-dark","from PIL import Image as PILImage\n\nPILImage.new(\"RGB\", (180, 56), color=\"#4472C4\").save(\"logo.png\")\nprint(\"Wrote logo.png (180x56)\")\n","python",[40,77,78,101,108,151],{"__ignoreMap":38},[43,79,80,84,88,91,95,98],{"class":45,"line":46},[43,81,83],{"class":82},"szBVR","from",[43,85,87],{"class":86},"sj4cs"," PIL",[43,89,90],{"class":82}," import",[43,92,94],{"class":93},"sVt8B"," Image ",[43,96,97],{"class":82},"as",[43,99,100],{"class":93}," PILImage\n",[43,102,104],{"class":45,"line":103},2,[43,105,107],{"emptyLinePlaceholder":106},true,"\n",[43,109,111,114,117,120,123,126,129,132,136,139,142,145,148],{"class":45,"line":110},3,[43,112,113],{"class":93},"PILImage.new(",[43,115,116],{"class":53},"\"RGB\"",[43,118,119],{"class":93},", (",[43,121,122],{"class":86},"180",[43,124,125],{"class":93},", ",[43,127,128],{"class":86},"56",[43,130,131],{"class":93},"), ",[43,133,135],{"class":134},"s4XuR","color",[43,137,138],{"class":82},"=",[43,140,141],{"class":53},"\"#4472C4\"",[43,143,144],{"class":93},").save(",[43,146,147],{"class":53},"\"logo.png\"",[43,149,150],{"class":93},")\n",[43,152,154,157,160,163],{"class":45,"line":153},4,[43,155,156],{"class":86},"print",[43,158,159],{"class":93},"(",[43,161,162],{"class":53},"\"Wrote logo.png (180x56)\"",[43,164,150],{"class":93},[20,166,168],{"id":167},"step-2-open-a-workbook-and-reserve-a-header-band","Step 2: open a workbook and reserve a header band",[10,170,171,172,175,176,179],{},"Start a workbook (or ",[40,173,174],{},"load_workbook(\"report.xlsx\")"," for an existing one) and make the first row tall enough to hold the logo. Remember that the image will ",[28,177,178],{},"float"," over the grid — it does not push rows down — so reserving height by hand is what keeps it from sitting on top of your data.",[33,181,183],{"className":73,"code":182,"language":75,"meta":38,"style":38},"from openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nws.title = \"Report\"\n\nws.row_dimensions[1].height = 50   # header band tall enough for the logo\nprint(\"Reserved a 50px header band on row 1\")\n",[40,184,185,198,202,212,222,233,238,259],{"__ignoreMap":38},[43,186,187,189,192,195],{"class":45,"line":46},[43,188,83],{"class":82},[43,190,191],{"class":93}," openpyxl ",[43,193,194],{"class":82},"import",[43,196,197],{"class":93}," Workbook\n",[43,199,200],{"class":45,"line":103},[43,201,107],{"emptyLinePlaceholder":106},[43,203,204,207,209],{"class":45,"line":110},[43,205,206],{"class":93},"wb ",[43,208,138],{"class":82},[43,210,211],{"class":93}," Workbook()\n",[43,213,214,217,219],{"class":45,"line":153},[43,215,216],{"class":93},"ws ",[43,218,138],{"class":82},[43,220,221],{"class":93}," wb.active\n",[43,223,225,228,230],{"class":45,"line":224},5,[43,226,227],{"class":93},"ws.title ",[43,229,138],{"class":82},[43,231,232],{"class":53}," \"Report\"\n",[43,234,236],{"class":45,"line":235},6,[43,237,107],{"emptyLinePlaceholder":106},[43,239,241,244,247,250,252,255],{"class":45,"line":240},7,[43,242,243],{"class":93},"ws.row_dimensions[",[43,245,246],{"class":86},"1",[43,248,249],{"class":93},"].height ",[43,251,138],{"class":82},[43,253,254],{"class":86}," 50",[43,256,258],{"class":257},"sJ8bj","   # header band tall enough for the logo\n",[43,260,262,264,266,269],{"class":45,"line":261},8,[43,263,156],{"class":86},[43,265,159],{"class":93},[43,267,268],{"class":53},"\"Reserved a 50px header band on row 1\"",[43,270,150],{"class":93},[20,272,274],{"id":273},"step-3-create-size-and-anchor-the-logo","Step 3: create, size, and anchor the logo",[10,276,277,278,281,282,285,286,289],{},"Build an ",[40,279,280],{},"openpyxl.drawing.image.Image",", scale it to fit the band ",[28,283,284],{},"without distorting it",", and anchor its top-left corner at A1 with ",[40,287,288],{},"ws.add_image",". To preserve the aspect ratio, read the source size with Pillow and scale by one factor instead of setting width and height blindly.",[33,291,293],{"className":73,"code":292,"language":75,"meta":38,"style":38},"from openpyxl.drawing.image import Image as XLImage\nfrom PIL import Image as PILImage\n\n# Measure the source so we scale proportionally\nwith PILImage.open(\"logo.png\") as src:\n    src_w, src_h = src.size\n\ntarget_h = 44                       # pixels, fits inside the 50px row\nscale = target_h \u002F src_h\nlogo = XLImage(\"logo.png\")\nlogo.height = target_h\nlogo.width = int(src_w * scale)     # same factor keeps proportions\n\nws.add_image(logo, \"A1\")            # anchor top-left at A1\nprint(f\"Logo sized to {logo.width}x{logo.height}px, anchored at A1\")\n",[40,294,295,311,325,329,334,352,362,366,379,396,411,422,445,450,465],{"__ignoreMap":38},[43,296,297,299,302,304,306,308],{"class":45,"line":46},[43,298,83],{"class":82},[43,300,301],{"class":93}," openpyxl.drawing.image ",[43,303,194],{"class":82},[43,305,94],{"class":93},[43,307,97],{"class":82},[43,309,310],{"class":93}," XLImage\n",[43,312,313,315,317,319,321,323],{"class":45,"line":103},[43,314,83],{"class":82},[43,316,87],{"class":86},[43,318,90],{"class":82},[43,320,94],{"class":93},[43,322,97],{"class":82},[43,324,100],{"class":93},[43,326,327],{"class":45,"line":110},[43,328,107],{"emptyLinePlaceholder":106},[43,330,331],{"class":45,"line":153},[43,332,333],{"class":257},"# Measure the source so we scale proportionally\n",[43,335,336,339,342,344,347,349],{"class":45,"line":224},[43,337,338],{"class":82},"with",[43,340,341],{"class":93}," PILImage.open(",[43,343,147],{"class":53},[43,345,346],{"class":93},") ",[43,348,97],{"class":82},[43,350,351],{"class":93}," src:\n",[43,353,354,357,359],{"class":45,"line":235},[43,355,356],{"class":93},"    src_w, src_h ",[43,358,138],{"class":82},[43,360,361],{"class":93}," src.size\n",[43,363,364],{"class":45,"line":240},[43,365,107],{"emptyLinePlaceholder":106},[43,367,368,371,373,376],{"class":45,"line":261},[43,369,370],{"class":93},"target_h ",[43,372,138],{"class":82},[43,374,375],{"class":86}," 44",[43,377,378],{"class":257},"                       # pixels, fits inside the 50px row\n",[43,380,382,385,387,390,393],{"class":45,"line":381},9,[43,383,384],{"class":93},"scale ",[43,386,138],{"class":82},[43,388,389],{"class":93}," target_h ",[43,391,392],{"class":82},"\u002F",[43,394,395],{"class":93}," src_h\n",[43,397,399,402,404,407,409],{"class":45,"line":398},10,[43,400,401],{"class":93},"logo ",[43,403,138],{"class":82},[43,405,406],{"class":93}," XLImage(",[43,408,147],{"class":53},[43,410,150],{"class":93},[43,412,414,417,419],{"class":45,"line":413},11,[43,415,416],{"class":93},"logo.height ",[43,418,138],{"class":82},[43,420,421],{"class":93}," target_h\n",[43,423,425,428,430,433,436,439,442],{"class":45,"line":424},12,[43,426,427],{"class":93},"logo.width ",[43,429,138],{"class":82},[43,431,432],{"class":86}," int",[43,434,435],{"class":93},"(src_w ",[43,437,438],{"class":82},"*",[43,440,441],{"class":93}," scale)     ",[43,443,444],{"class":257},"# same factor keeps proportions\n",[43,446,448],{"class":45,"line":447},13,[43,449,107],{"emptyLinePlaceholder":106},[43,451,453,456,459,462],{"class":45,"line":452},14,[43,454,455],{"class":93},"ws.add_image(logo, ",[43,457,458],{"class":53},"\"A1\"",[43,460,461],{"class":93},")            ",[43,463,464],{"class":257},"# anchor top-left at A1\n",[43,466,468,470,472,475,478,481,484,487,490,492,495,497,500],{"class":45,"line":467},15,[43,469,156],{"class":86},[43,471,159],{"class":93},[43,473,474],{"class":82},"f",[43,476,477],{"class":53},"\"Logo sized to ",[43,479,480],{"class":86},"{",[43,482,483],{"class":93},"logo.width",[43,485,486],{"class":86},"}",[43,488,489],{"class":53},"x",[43,491,480],{"class":86},[43,493,494],{"class":93},"logo.height",[43,496,486],{"class":86},[43,498,499],{"class":53},"px, anchored at A1\"",[43,501,150],{"class":93},[20,503,505],{"id":504},"step-4-add-a-merged-title-beside-the-logo","Step 4: add a merged title beside the logo",[10,507,508],{},"Put the report title to the right of the logo by merging a few cells in row 1 and styling the anchor cell. Merging gives the title room and centers it vertically against the tall band.",[33,510,512],{"className":73,"code":511,"language":75,"meta":38,"style":38},"from openpyxl.styles import Font, Alignment\n\nws.merge_cells(\"B1:F1\")\ntitle = ws[\"B1\"]\ntitle.value = \"Q2 Sales Report\"\ntitle.font = Font(bold=True, size=16, color=\"1F3864\")\ntitle.alignment = Alignment(horizontal=\"left\", vertical=\"center\")\nprint(\"Merged B1:F1 and set the title\")\n",[40,513,514,526,530,540,556,566,605,635],{"__ignoreMap":38},[43,515,516,518,521,523],{"class":45,"line":46},[43,517,83],{"class":82},[43,519,520],{"class":93}," openpyxl.styles ",[43,522,194],{"class":82},[43,524,525],{"class":93}," Font, Alignment\n",[43,527,528],{"class":45,"line":103},[43,529,107],{"emptyLinePlaceholder":106},[43,531,532,535,538],{"class":45,"line":110},[43,533,534],{"class":93},"ws.merge_cells(",[43,536,537],{"class":53},"\"B1:F1\"",[43,539,150],{"class":93},[43,541,542,545,547,550,553],{"class":45,"line":153},[43,543,544],{"class":93},"title ",[43,546,138],{"class":82},[43,548,549],{"class":93}," ws[",[43,551,552],{"class":53},"\"B1\"",[43,554,555],{"class":93},"]\n",[43,557,558,561,563],{"class":45,"line":224},[43,559,560],{"class":93},"title.value ",[43,562,138],{"class":82},[43,564,565],{"class":53}," \"Q2 Sales Report\"\n",[43,567,568,571,573,576,579,581,584,586,589,591,594,596,598,600,603],{"class":45,"line":235},[43,569,570],{"class":93},"title.font ",[43,572,138],{"class":82},[43,574,575],{"class":93}," Font(",[43,577,578],{"class":134},"bold",[43,580,138],{"class":82},[43,582,583],{"class":86},"True",[43,585,125],{"class":93},[43,587,588],{"class":134},"size",[43,590,138],{"class":82},[43,592,593],{"class":86},"16",[43,595,125],{"class":93},[43,597,135],{"class":134},[43,599,138],{"class":82},[43,601,602],{"class":53},"\"1F3864\"",[43,604,150],{"class":93},[43,606,607,610,612,615,618,620,623,625,628,630,633],{"class":45,"line":240},[43,608,609],{"class":93},"title.alignment ",[43,611,138],{"class":82},[43,613,614],{"class":93}," Alignment(",[43,616,617],{"class":134},"horizontal",[43,619,138],{"class":82},[43,621,622],{"class":53},"\"left\"",[43,624,125],{"class":93},[43,626,627],{"class":134},"vertical",[43,629,138],{"class":82},[43,631,632],{"class":53},"\"center\"",[43,634,150],{"class":93},[43,636,637,639,641,644],{"class":45,"line":261},[43,638,156],{"class":86},[43,640,159],{"class":93},[43,642,643],{"class":53},"\"Merged B1:F1 and set the title\"",[43,645,150],{"class":93},[20,647,649],{"id":648},"step-5-add-data-and-save","Step 5: add data and save",[10,651,652,653,656,657,660],{},"Write the table starting below the band so nothing overlaps, then save ",[28,654,655],{},"while the PNG still exists on disk"," — openpyxl reads the image bytes at save time, not when you construct the ",[40,658,659],{},"Image",".",[33,662,664],{"className":73,"code":663,"language":75,"meta":38,"style":38},"ws.append([])                       # spacer row 2\nws.append([\"Region\", \"Revenue\"])    # header row 3\nfor region, revenue in [(\"North\", 25640), (\"South\", 18890), (\"East\", 31200)]:\n    ws.append([region, revenue])\n\nwb.save(\"branded_report.xlsx\")\nprint(\"Saved branded_report.xlsx with logo and title\")\n",[40,665,666,674,693,739,744,748,758],{"__ignoreMap":38},[43,667,668,671],{"class":45,"line":46},[43,669,670],{"class":93},"ws.append([])                       ",[43,672,673],{"class":257},"# spacer row 2\n",[43,675,676,679,682,684,687,690],{"class":45,"line":103},[43,677,678],{"class":93},"ws.append([",[43,680,681],{"class":53},"\"Region\"",[43,683,125],{"class":93},[43,685,686],{"class":53},"\"Revenue\"",[43,688,689],{"class":93},"])    ",[43,691,692],{"class":257},"# header row 3\n",[43,694,695,698,701,704,707,710,712,715,718,721,723,726,728,731,733,736],{"class":45,"line":110},[43,696,697],{"class":82},"for",[43,699,700],{"class":93}," region, revenue ",[43,702,703],{"class":82},"in",[43,705,706],{"class":93}," [(",[43,708,709],{"class":53},"\"North\"",[43,711,125],{"class":93},[43,713,714],{"class":86},"25640",[43,716,717],{"class":93},"), (",[43,719,720],{"class":53},"\"South\"",[43,722,125],{"class":93},[43,724,725],{"class":86},"18890",[43,727,717],{"class":93},[43,729,730],{"class":53},"\"East\"",[43,732,125],{"class":93},[43,734,735],{"class":86},"31200",[43,737,738],{"class":93},")]:\n",[43,740,741],{"class":45,"line":153},[43,742,743],{"class":93},"    ws.append([region, revenue])\n",[43,745,746],{"class":45,"line":224},[43,747,107],{"emptyLinePlaceholder":106},[43,749,750,753,756],{"class":45,"line":235},[43,751,752],{"class":93},"wb.save(",[43,754,755],{"class":53},"\"branded_report.xlsx\"",[43,757,150],{"class":93},[43,759,760,762,764,767],{"class":45,"line":240},[43,761,156],{"class":86},[43,763,159],{"class":93},[43,765,766],{"class":53},"\"Saved branded_report.xlsx with logo and title\"",[43,768,150],{"class":93},[10,770,771,772,775],{},"Run steps 1-5 in one script and you get ",[40,773,774],{},"branded_report.xlsx",": a self-contained workbook with the logo anchored at A1, a title beside it, and the table below — emailable, with the logo embedded inside the file.",[20,777,779],{"id":778},"common-pitfalls","Common pitfalls",[781,782,783,799],"table",{},[784,785,786],"thead",{},[787,788,789,793,796],"tr",{},[790,791,792],"th",{},"Error \u002F symptom",[790,794,795],{},"Cause",[790,797,798],{},"Fix",[800,801,802,822,837,857,875],"tbody",{},[787,803,804,814,817],{},[805,806,807,810,811],"td",{},[40,808,809],{},"ImportError"," when building ",[40,812,813],{},"Image(...)",[805,815,816],{},"Pillow not installed",[805,818,819],{},[40,820,821],{},"pip install pillow",[787,823,824,827,830],{},[805,825,826],{},"Logo overlaps the data rows",[805,828,829],{},"Images float and never push cells down",[805,831,832,833,836],{},"Reserve room with ",[40,834,835],{},"ws.row_dimensions[1].height"," and start data below",[787,838,839,848,851],{},[805,840,841,844,845],{},[40,842,843],{},"FileNotFoundError"," on ",[40,846,847],{},"wb.save()",[805,849,850],{},"Source PNG deleted before the save",[805,852,853,854,856],{},"Keep the file on disk until after ",[40,855,847],{}," runs",[787,858,859,862,872],{},[805,860,861],{},"Logo looks stretched",[805,863,864,867,868,871],{},[40,865,866],{},"width"," and ",[40,869,870],{},"height"," set independently",[805,873,874],{},"Scale both by one factor from the source size (Step 3)",[787,876,877,880,887],{},[805,878,879],{},"Logo vanished after a later edit",[805,881,882,883,886],{},"File was rewritten with ",[40,884,885],{},"pandas.to_excel",", which drops drawings",[805,888,889,890,893],{},"Make openpyxl the ",[28,891,892],{},"last"," writer; never resave with pandas afterward",[10,895,896,897,900,901,903,904,907],{},"The deletion trap is worth stressing: openpyxl does not slurp the image when you call ",[40,898,899],{},"Image(\"logo.png\")"," — it reads the bytes during ",[40,902,847],{},". If you generate a temp PNG and ",[40,905,906],{},"os.remove"," it before saving, the save fails or the image is missing. Delete temp files only after the workbook is written.",[10,909,910,911,915],{},"A quick note on the floating model: anchoring at A1 sets where the logo ",[912,913,914],"em",{},"starts",", not which cells it covers. A logo wider than column A spills over B and C, which is fine for a header band but means widening column A alone will not \"contain\" it. Reserve space with row height and column width together if you need a tidy boxed logo.",[20,917,919],{"id":918},"frequently-asked-questions","Frequently asked questions",[10,921,922,925,926,928,929,931],{},[28,923,924],{},"Do I have to install Pillow just for one logo?","\nYes. openpyxl delegates all image reading to Pillow, so even a single PNG requires it. The ",[40,927,813],{}," constructor raises ",[40,930,809],{}," without it.",[10,933,934,937],{},[28,935,936],{},"Why anchor at A1 instead of putting the image \"in\" the cell?","\nExcel has no concept of an image inside a cell. Images are floating drawings anchored to a corner cell. Anchoring at A1 places the logo's top-left there; the image then floats over whatever cells it spans.",[10,939,940,943,944,867,946,948],{},[28,941,942],{},"How do I keep the logo from looking squashed?","\nDo not set ",[40,945,866],{},[40,947,870],{}," to arbitrary numbers. Read the source dimensions with Pillow and multiply both by the same scale factor (Step 3). Setting one to a value and the other independently is what distorts it.",[10,950,951,954,955,958,959,961],{},[28,952,953],{},"Can I do this on an existing report instead of a new workbook?","\nYes. Replace ",[40,956,957],{},"Workbook()"," in Step 2 with ",[40,960,174],{}," and pick the sheet you want. openpyxl preserves the existing data and styles while you add the logo.",[10,963,964,967,968,970],{},[28,965,966],{},"The logo disappeared after I regenerated the file — why?","\nSomething rewrote the workbook with ",[40,969,885],{},", which rebuilds the sheet from the DataFrame and discards images, charts, and most styling. Add the logo as the last step and never round-trip the file back through pandas.",[20,972,974],{"id":973},"conclusion","Conclusion",[10,976,977,978,980],{},"Adding a logo is five steps: make (or point at) the PNG, reserve a header band with row height, build and proportionally size the ",[40,979,659],{},", anchor it at A1 with a merged title beside it, and save while the source file still exists. Keep openpyxl as the last tool to write the file and your logo stays put. Pillow is non-negotiable, and the float model — images sit over cells, never inside them — explains every layout quirk you will hit.",[20,982,984],{"id":983},"where-to-go-next","Where to go next",[10,986,987],{},"Up to the parent cluster:",[989,990,991],"ul",{},[992,993,994,996],"li",{},[14,995,17],{"href":16}," — the concepts behind anchoring, resizing, and pandas-safe sequencing.",[10,998,999],{},"Related pages:",[989,1001,1002,1009],{},[992,1003,1004,1008],{},[14,1005,1007],{"href":1006},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002F","Using openpyxl for Excel File Manipulation"," — loading, editing, and saving workbooks, the foundation this recipe stands on.",[992,1010,1011,1015],{},[14,1012,1014],{"href":1013},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002F","Building Multi-Sheet Excel Dashboards"," — assemble branded, logo-topped sheets into a single dashboard workbook.",[1017,1018,1019],"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 .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":38,"searchDepth":103,"depth":103,"links":1021},[1022,1023,1024,1025,1026,1027,1028,1029,1030,1031],{"id":22,"depth":103,"text":23},{"id":66,"depth":103,"text":67},{"id":167,"depth":103,"text":168},{"id":273,"depth":103,"text":274},{"id":504,"depth":103,"text":505},{"id":648,"depth":103,"text":649},{"id":778,"depth":103,"text":779},{"id":918,"depth":103,"text":919},{"id":973,"depth":103,"text":974},{"id":983,"depth":103,"text":984},"Step-by-step openpyxl guide to add a logo to an Excel report: create the image, anchor it at A1, size it to a header band, add a merged title, and save.","md",{},"\u002Fformatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel\u002Fadd-logo-image-to-excel-report-with-openpyxl",{"title":1037,"description":1038},"Add a Logo to an Excel Report with openpyxl","Embed a logo in an Excel report using openpyxl and Pillow: build the Image, anchor at A1, resize to a header band, add a merged title, and avoid lost images.","formatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel\u002Fadd-logo-image-to-excel-report-with-openpyxl\u002Findex","5zZH-H1QnhvyDViky54m4Gkk6wLgb5pbmNgVzmabGsk",[1042,1045],{"title":17,"path":1043,"stem":1044,"children":-1},"\u002Fformatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel","formatting-and-charting-excel-reports-with-python\u002Finserting-images-and-logos-into-excel\u002Findex",{"title":1046,"path":1047,"stem":1048,"children":-1},"Styling Excel Cells with openpyxl","\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl","formatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Findex",1781773161037]