[{"data":1,"prerenderedAt":2428},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-clickable-links-from-a-dataframe-to-excel":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-clickable-links-from-a-dataframe-to-excel":2394,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-clickable-links-from-a-dataframe-to-excel":2403,"children:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-clickable-links-from-a-dataframe-to-excel":2408,"related:\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-clickable-links-from-a-dataframe-to-excel":2409},{"id":4,"title":5,"body":6,"dateModified":2359,"datePublished":2359,"description":2360,"extension":2361,"faq":2362,"keyword":2371,"kind":2372,"meta":2373,"navigation":309,"path":2382,"seo":2383,"slug":2386,"stem":2387,"topics":2388,"type":2392,"__hash__":2393},"docs\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-clickable-links-from-a-dataframe-to-excel\u002Findex.md","Write Clickable Links from a DataFrame Column to Excel",{"type":7,"value":8,"toc":2346},"minimark",[9,19,231,236,267,482,486,510,611,627,631,641,848,851,855,858,1100,1116,1297,1300,1426,1429,1433,1444,1712,1719,1723,1734,1862,1869,1906,1919,2034,2041,2199,2205,2209,2259,2263,2266,2270,2281,2285,2291,2297,2303,2309,2313,2342],[10,11,12,13,18],"p",{},"A report of support tickets, orders or documents usually has a URL for each row, and readers expect to click it. Whether the column comes out clickable depends on the engine pandas uses: with xlsxwriter, URLs become links automatically; with openpyxl, they are plain text. Neither shows friendly text like \"Open ticket\" instead of a long address. This page, part of ",[14,15,17],"a",{"href":16},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002F","Writing DataFrames to Excel with Pandas",", shows three ways to write links from a DataFrame, which to choose, and two limits that silently lose data if you do not plan for them.",[20,21,29,30,29,34,29,38,29,46,29,56,29,67,29,74,29,81,29,87,29,95,29,99,29,104,29,108,29,115,29,119,29,124,29,129,29,136,29,141,29,145,29,149,29,154,29,157,29,162,29,165,29,170,29,173,29,178,29,182,29,189,29,194,29,198,29,202,29,207,29,210,29,215,29,218,29,223,29,226],"svg",{"viewBox":22,"role":23,"ariaLabelledBy":24,"xmlns":27,"style":28},"4 0 752 233","img",[25,26],"lnk-ways-t","lnk-ways-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[31,32,33],"title",{"id":25},"Three ways to make a DataFrame column clickable",[35,36,37],"desc",{"id":26},"Three panels. Automatic URL detection with the xlsxwriter engine needs no code but shows the raw URL. HYPERLINK formulas show friendly text, work with either engine, but the cell holds a formula and URLs are limited to 255 characters inside it. openpyxl cell.hyperlink after writing shows any text, keeps the cell a plain value and supports links to other sheets.",[39,40],"rect",{"x":41,"y":42,"width":43,"height":44,"fill":45},"4","0","752","233","#ffffff",[39,47],{"x":48,"y":49,"width":50,"height":51,"rx":52,"fill":53,"stroke":54,"style":55},"20.0","16.0","228.0","201.0","14","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:2px",[57,58,60],"g",{"transform":59},"translate(121.0,29.0) scale(1.083)",[61,62],"path",{"d":63,"fill":64,"stroke":65,"style":66},"M13 2L4 14h7l-1 8 9-12h-7z","none","var(--brand-strong,#4338ca)","stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[68,69,73],"text",{"x":70,"y":71,"style":72},"134.0","78.0","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","xlsxwriter auto-links",[75,76],"line",{"x1":77,"y1":78,"x2":79,"y2":78,"stroke":54,"style":80},"36.0","91.0","232.0","stroke-width:1px",[68,82,86],{"x":83,"y":84,"style":85},"60.0","111.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","no extra code",[57,88,90],{"transform":89},"translate(38.5,99.5) scale(0.625)",[61,91],{"d":92,"fill":64,"stroke":93,"style":94},"M5 12.5l4.5 4.5L19 7","var(--teal,#0f9488)","stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[68,96,98],{"x":83,"y":97,"style":85},"137.0","link styling applied",[57,100,102],{"transform":101},"translate(38.5,125.5) scale(0.625)",[61,103],{"d":92,"fill":64,"stroke":93,"style":94},[68,105,107],{"x":83,"y":106,"style":85},"163.0","shows the raw URL",[57,109,111],{"transform":110},"translate(38.5,151.5) scale(0.625)",[61,112],{"d":113,"fill":64,"stroke":114,"style":94},"M6 6l12 12 M18 6L6 18","var(--accent,#f43f8f)",[68,116,118],{"x":83,"y":117,"style":85},"189.0","xlsxwriter engine only",[57,120,122],{"transform":121},"translate(38.5,177.5) scale(0.625)",[61,123],{"d":113,"fill":64,"stroke":114,"style":94},[39,125],{"x":126,"y":49,"width":50,"height":51,"rx":52,"fill":127,"stroke":128,"style":55},"266.0","#fdefd8","var(--gold,#b4740a)",[57,130,132],{"transform":131},"translate(367.0,29.0) scale(1.083)",[61,133],{"d":134,"fill":64,"stroke":135,"style":66},"M9 8l-4 4 4 4 M15 8l4 4-4 4","var(--gold-ink,#7a4e06)",[68,137,140],{"x":138,"y":71,"style":139},"380.0","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","=HYPERLINK() formulas",[75,142],{"x1":143,"y1":78,"x2":144,"y2":78,"stroke":128,"style":80},"282.0","478.0",[68,146,148],{"x":147,"y":84,"style":85},"306.0","friendly display text",[57,150,152],{"transform":151},"translate(284.5,99.5) scale(0.625)",[61,153],{"d":92,"fill":64,"stroke":93,"style":94},[68,155,156],{"x":147,"y":97,"style":85},"either engine",[57,158,160],{"transform":159},"translate(284.5,125.5) scale(0.625)",[61,161],{"d":92,"fill":64,"stroke":93,"style":94},[68,163,164],{"x":147,"y":106,"style":85},"cell holds a formula",[57,166,168],{"transform":167},"translate(284.5,151.5) scale(0.625)",[61,169],{"d":113,"fill":64,"stroke":114,"style":94},[68,171,172],{"x":147,"y":117,"style":85},"255-character strings",[57,174,176],{"transform":175},"translate(284.5,177.5) scale(0.625)",[61,177],{"d":113,"fill":64,"stroke":114,"style":94},[39,179],{"x":180,"y":49,"width":50,"height":51,"rx":52,"fill":181,"stroke":93,"style":55},"512.0","#d9f4f1",[57,183,185],{"transform":184},"translate(613.0,29.0) scale(1.083)",[61,186],{"d":187,"fill":64,"stroke":188,"style":66},"M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1 M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1","var(--teal-ink,#0b6157)",[68,190,193],{"x":191,"y":71,"style":192},"626.0","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","openpyxl cell.hyperlink",[75,195],{"x1":196,"y1":78,"x2":197,"y2":78,"stroke":93,"style":80},"528.0","724.0",[68,199,201],{"x":200,"y":84,"style":85},"552.0","any display text",[57,203,205],{"transform":204},"translate(530.5,99.5) scale(0.625)",[61,206],{"d":92,"fill":64,"stroke":93,"style":94},[68,208,209],{"x":200,"y":97,"style":85},"cell stays a value",[57,211,213],{"transform":212},"translate(530.5,125.5) scale(0.625)",[61,214],{"d":92,"fill":64,"stroke":93,"style":94},[68,216,217],{"x":200,"y":106,"style":85},"links to other sheets",[57,219,221],{"transform":220},"translate(530.5,151.5) scale(0.625)",[61,222],{"d":92,"fill":64,"stroke":93,"style":94},[68,224,225],{"x":200,"y":117,"style":85},"a second pass",[57,227,229],{"transform":228},"translate(530.5,177.5) scale(0.625)",[61,230],{"d":113,"fill":64,"stroke":114,"style":94},[232,233,235],"h2",{"id":234},"prerequisites","Prerequisites",[237,238,243],"pre",{"className":239,"code":240,"language":241,"meta":242,"style":242},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl xlsxwriter\n","bash","",[244,245,246],"code",{"__ignoreMap":242},[247,248,250,254,258,261,264],"span",{"class":75,"line":249},1,[247,251,253],{"class":252},"sMTad","pip",[247,255,257],{"class":256},"srMev"," install",[247,259,260],{"class":256}," pandas",[247,262,263],{"class":256}," openpyxl",[247,265,266],{"class":256}," xlsxwriter\n",[237,268,272],{"className":269,"code":270,"language":271,"meta":242,"style":242},"language-python shiki shiki-themes github-light github-dark-high-contrast","import pandas as pd\nfrom openpyxl import load_workbook\n\ntickets = pd.DataFrame({\n    \"ticket\": [\"T-101\", \"T-102\", \"T-103\"],\n    \"status\": [\"open\", \"waiting\", \"closed\"],\n    \"url\": [\"https:\u002F\u002Fsupport.example.com\u002Ft\u002F101\",\n            \"https:\u002F\u002Fsupport.example.com\u002Ft\u002F102\",\n            \"https:\u002F\u002Fsupport.example.com\u002Ft\u002F103\"],\n})\n\ndef describe(path, row=2):\n    ws = load_workbook(path).active\n    return [(c.value, c.hyperlink.target if c.hyperlink else None) for c in ws[row]]\n","python",[244,273,274,290,304,311,323,349,372,386,394,402,408,413,435,446],{"__ignoreMap":242},[247,275,276,280,284,287],{"class":75,"line":249},[247,277,279],{"class":278},"s-kum","import",[247,281,283],{"class":282},"skGVy"," pandas ",[247,285,286],{"class":278},"as",[247,288,289],{"class":282}," pd\n",[247,291,293,296,299,301],{"class":75,"line":292},2,[247,294,295],{"class":278},"from",[247,297,298],{"class":282}," openpyxl ",[247,300,279],{"class":278},[247,302,303],{"class":282}," load_workbook\n",[247,305,307],{"class":75,"line":306},3,[247,308,310],{"emptyLinePlaceholder":309},true,"\n",[247,312,314,317,320],{"class":75,"line":313},4,[247,315,316],{"class":282},"tickets ",[247,318,319],{"class":278},"=",[247,321,322],{"class":282}," pd.DataFrame({\n",[247,324,326,329,332,335,338,341,343,346],{"class":75,"line":325},5,[247,327,328],{"class":256},"    \"ticket\"",[247,330,331],{"class":282},": [",[247,333,334],{"class":256},"\"T-101\"",[247,336,337],{"class":282},", ",[247,339,340],{"class":256},"\"T-102\"",[247,342,337],{"class":282},[247,344,345],{"class":256},"\"T-103\"",[247,347,348],{"class":282},"],\n",[247,350,352,355,357,360,362,365,367,370],{"class":75,"line":351},6,[247,353,354],{"class":256},"    \"status\"",[247,356,331],{"class":282},[247,358,359],{"class":256},"\"open\"",[247,361,337],{"class":282},[247,363,364],{"class":256},"\"waiting\"",[247,366,337],{"class":282},[247,368,369],{"class":256},"\"closed\"",[247,371,348],{"class":282},[247,373,375,378,380,383],{"class":75,"line":374},7,[247,376,377],{"class":256},"    \"url\"",[247,379,331],{"class":282},[247,381,382],{"class":256},"\"https:\u002F\u002Fsupport.example.com\u002Ft\u002F101\"",[247,384,385],{"class":282},",\n",[247,387,389,392],{"class":75,"line":388},8,[247,390,391],{"class":256},"            \"https:\u002F\u002Fsupport.example.com\u002Ft\u002F102\"",[247,393,385],{"class":282},[247,395,397,400],{"class":75,"line":396},9,[247,398,399],{"class":256},"            \"https:\u002F\u002Fsupport.example.com\u002Ft\u002F103\"",[247,401,348],{"class":282},[247,403,405],{"class":75,"line":404},10,[247,406,407],{"class":282},"})\n",[247,409,411],{"class":75,"line":410},11,[247,412,310],{"emptyLinePlaceholder":309},[247,414,416,419,423,426,428,432],{"class":75,"line":415},12,[247,417,418],{"class":278},"def",[247,420,422],{"class":421},"s_Opv"," describe",[247,424,425],{"class":282},"(path, row",[247,427,319],{"class":278},[247,429,431],{"class":430},"sP0c6","2",[247,433,434],{"class":282},"):\n",[247,436,438,441,443],{"class":75,"line":437},13,[247,439,440],{"class":282},"    ws ",[247,442,319],{"class":278},[247,444,445],{"class":282}," load_workbook(path).active\n",[247,447,449,452,455,458,461,464,467,470,473,476,479],{"class":75,"line":448},14,[247,450,451],{"class":278},"    return",[247,453,454],{"class":282}," [(c.value, c.hyperlink.target ",[247,456,457],{"class":278},"if",[247,459,460],{"class":282}," c.hyperlink ",[247,462,463],{"class":278},"else",[247,465,466],{"class":430}," None",[247,468,469],{"class":282},") ",[247,471,472],{"class":278},"for",[247,474,475],{"class":282}," c ",[247,477,478],{"class":278},"in",[247,480,481],{"class":282}," ws[row]]\n",[232,483,485],{"id":484},"step-1-let-xlsxwriter-detect-the-urls","Step 1 — Let xlsxwriter detect the URLs",[10,487,488,489,492,493,337,496,337,499,337,502,505,506,509],{},"With the xlsxwriter engine, pandas writes each string through xlsxwriter's general ",[244,490,491],{},"write()"," method, which recognises strings that start with ",[244,494,495],{},"http:\u002F\u002F",[244,497,498],{},"https:\u002F\u002F",[244,500,501],{},"ftp:\u002F\u002F",[244,503,504],{},"file:\u002F\u002F"," or ",[244,507,508],{},"mailto:"," and writes them as hyperlinks with Excel's blue, underlined hyperlink style:",[237,511,513],{"className":269,"code":512,"language":271,"meta":242,"style":242},"tickets.to_excel(\"auto_links.xlsx\", index=False, engine=\"xlsxwriter\")\nprint(describe(\"auto_links.xlsx\"))\n# [('T-101', None), ('open', None), ('https:\u002F\u002Fsupport.example.com\u002Ft\u002F101', 'https:\u002F\u002Fsupport.example.com\u002Ft\u002F101')]\n\ntickets.to_excel(\"plain.xlsx\", index=False, engine=\"openpyxl\")\nprint(describe(\"plain.xlsx\"))\n# [('T-101', None), ('open', None), ('https:\u002F\u002Fsupport.example.com\u002Ft\u002F101', None)]\n",[244,514,515,547,560,566,570,596,606],{"__ignoreMap":242},[247,516,517,520,523,525,529,531,534,536,539,541,544],{"class":75,"line":249},[247,518,519],{"class":282},"tickets.to_excel(",[247,521,522],{"class":256},"\"auto_links.xlsx\"",[247,524,337],{"class":282},[247,526,528],{"class":527},"sa561","index",[247,530,319],{"class":278},[247,532,533],{"class":430},"False",[247,535,337],{"class":282},[247,537,538],{"class":527},"engine",[247,540,319],{"class":278},[247,542,543],{"class":256},"\"xlsxwriter\"",[247,545,546],{"class":282},")\n",[247,548,549,552,555,557],{"class":75,"line":292},[247,550,551],{"class":430},"print",[247,553,554],{"class":282},"(describe(",[247,556,522],{"class":256},[247,558,559],{"class":282},"))\n",[247,561,562],{"class":75,"line":306},[247,563,565],{"class":564},"s-wDw","# [('T-101', None), ('open', None), ('https:\u002F\u002Fsupport.example.com\u002Ft\u002F101', 'https:\u002F\u002Fsupport.example.com\u002Ft\u002F101')]\n",[247,567,568],{"class":75,"line":313},[247,569,310],{"emptyLinePlaceholder":309},[247,571,572,574,577,579,581,583,585,587,589,591,594],{"class":75,"line":325},[247,573,519],{"class":282},[247,575,576],{"class":256},"\"plain.xlsx\"",[247,578,337],{"class":282},[247,580,528],{"class":527},[247,582,319],{"class":278},[247,584,533],{"class":430},[247,586,337],{"class":282},[247,588,538],{"class":527},[247,590,319],{"class":278},[247,592,593],{"class":256},"\"openpyxl\"",[247,595,546],{"class":282},[247,597,598,600,602,604],{"class":75,"line":351},[247,599,551],{"class":430},[247,601,554],{"class":282},[247,603,576],{"class":256},[247,605,559],{"class":282},[247,607,608],{"class":75,"line":374},[247,609,610],{"class":564},"# [('T-101', None), ('open', None), ('https:\u002F\u002Fsupport.example.com\u002Ft\u002F101', None)]\n",[10,612,613,614,618,619,622,623,626],{},"That is the whole solution when the raw URL is an acceptable thing to show. It is also a behaviour to know about when it is ",[615,616,617],"em",{},"not"," wanted — a column of example URLs in documentation, say. Turn it off with ",[244,620,621],{},"engine_kwargs={\"options\": {\"strings_to_urls\": False}}"," on the ",[244,624,625],{},"ExcelWriter",".",[232,628,630],{"id":629},"step-2-show-friendly-text-with-hyperlink-formulas","Step 2 — Show friendly text with HYPERLINK formulas",[10,632,633,634,637,638,640],{},"To show \"Open T-101\" and link to the address, build an Excel ",[244,635,636],{},"HYPERLINK"," formula in the column. Both engines write strings starting with ",[244,639,319],{}," as formulas:",[237,642,644],{"className":269,"code":643,"language":271,"meta":242,"style":242},"def hyperlink(url, text):\n    url = str(url).replace('\"', '\"\"')\n    text = str(text).replace('\"', '\"\"')\n    return f'=HYPERLINK(\"{url}\",\"{text}\")'\n\nout = tickets.assign(link=[hyperlink(u, f\"Open {t}\") for u, t in zip(tickets[\"url\"], tickets[\"ticket\"])])\nout = out.drop(columns=\"url\")\nout.to_excel(\"formula_links.xlsx\", index=False)\nprint(describe(\"formula_links.xlsx\")[2])\n",[244,645,646,656,679,699,731,735,796,814,832],{"__ignoreMap":242},[247,647,648,650,653],{"class":75,"line":249},[247,649,418],{"class":278},[247,651,652],{"class":421}," hyperlink",[247,654,655],{"class":282},"(url, text):\n",[247,657,658,661,663,666,669,672,674,677],{"class":75,"line":292},[247,659,660],{"class":282},"    url ",[247,662,319],{"class":278},[247,664,665],{"class":430}," str",[247,667,668],{"class":282},"(url).replace(",[247,670,671],{"class":256},"'\"'",[247,673,337],{"class":282},[247,675,676],{"class":256},"'\"\"'",[247,678,546],{"class":282},[247,680,681,684,686,688,691,693,695,697],{"class":75,"line":306},[247,682,683],{"class":282},"    text ",[247,685,319],{"class":278},[247,687,665],{"class":430},[247,689,690],{"class":282},"(text).replace(",[247,692,671],{"class":256},[247,694,337],{"class":282},[247,696,676],{"class":256},[247,698,546],{"class":282},[247,700,701,703,706,709,713,716,719,722,724,726,728],{"class":75,"line":313},[247,702,451],{"class":278},[247,704,705],{"class":278}," f",[247,707,708],{"class":256},"'=HYPERLINK(\"",[247,710,712],{"class":711},"sSjpA","{",[247,714,715],{"class":282},"url",[247,717,718],{"class":711},"}",[247,720,721],{"class":256},"\",\"",[247,723,712],{"class":711},[247,725,68],{"class":282},[247,727,718],{"class":711},[247,729,730],{"class":256},"\")'\n",[247,732,733],{"class":75,"line":325},[247,734,310],{"emptyLinePlaceholder":309},[247,736,737,740,742,745,748,750,753,756,759,761,764,766,769,771,773,776,778,781,784,787,790,793],{"class":75,"line":351},[247,738,739],{"class":282},"out ",[247,741,319],{"class":278},[247,743,744],{"class":282}," tickets.assign(",[247,746,747],{"class":527},"link",[247,749,319],{"class":278},[247,751,752],{"class":282},"[hyperlink(u, ",[247,754,755],{"class":278},"f",[247,757,758],{"class":256},"\"Open ",[247,760,712],{"class":711},[247,762,763],{"class":282},"t",[247,765,718],{"class":711},[247,767,768],{"class":256},"\"",[247,770,469],{"class":282},[247,772,472],{"class":278},[247,774,775],{"class":282}," u, t ",[247,777,478],{"class":278},[247,779,780],{"class":430}," zip",[247,782,783],{"class":282},"(tickets[",[247,785,786],{"class":256},"\"url\"",[247,788,789],{"class":282},"], tickets[",[247,791,792],{"class":256},"\"ticket\"",[247,794,795],{"class":282},"])])\n",[247,797,798,800,802,805,808,810,812],{"class":75,"line":374},[247,799,739],{"class":282},[247,801,319],{"class":278},[247,803,804],{"class":282}," out.drop(",[247,806,807],{"class":527},"columns",[247,809,319],{"class":278},[247,811,786],{"class":256},[247,813,546],{"class":282},[247,815,816,819,822,824,826,828,830],{"class":75,"line":388},[247,817,818],{"class":282},"out.to_excel(",[247,820,821],{"class":256},"\"formula_links.xlsx\"",[247,823,337],{"class":282},[247,825,528],{"class":527},[247,827,319],{"class":278},[247,829,533],{"class":430},[247,831,546],{"class":282},[247,833,834,836,838,840,843,845],{"class":75,"line":396},[247,835,551],{"class":430},[247,837,554],{"class":282},[247,839,821],{"class":256},[247,841,842],{"class":282},")[",[247,844,431],{"class":430},[247,846,847],{"class":282},"])\n",[10,849,850],{},"Doubling any quotes inside the URL or text keeps the formula valid. The formula approach has two costs. The cell's value is now a formula, so anyone reading the file back with pandas gets the formula text, not the URL. And Excel limits text strings inside a formula to 255 characters, so long tracking URLs do not fit. Cells written this way also lack the hyperlink style unless you add it, though Excel applies it once the formula is edited.",[232,852,854],{"id":853},"step-3-attach-links-with-openpyxl-after-writing","Step 3 — Attach links with openpyxl after writing",[10,856,857],{},"The most flexible method writes the display text with pandas, then opens the workbook with openpyxl and attaches the URL to each cell. The cell keeps a plain value, the link can point anywhere, and the built-in \"Hyperlink\" style gives it the familiar look:",[237,859,861],{"className":269,"code":860,"language":271,"meta":242,"style":242},"report = tickets.assign(link=[f\"Open {t}\" for t in tickets[\"ticket\"]])\nreport.drop(columns=\"url\").to_excel(\"attached_links.xlsx\", index=False)\n\nwb = load_workbook(\"attached_links.xlsx\")\nws = wb.active\nlink_col = [c.value for c in ws[1]].index(\"link\") + 1\nfor row, url in enumerate(tickets[\"url\"], start=2):\n    cell = ws.cell(row=row, column=link_col)\n    cell.hyperlink = url\n    cell.style = \"Hyperlink\"\nwb.save(\"attached_links.xlsx\")\nprint(describe(\"attached_links.xlsx\")[2])\n# ('Open T-101', 'https:\u002F\u002Fsupport.example.com\u002Ft\u002F101')\n",[244,862,863,907,934,938,952,962,998,1026,1052,1062,1072,1081,1095],{"__ignoreMap":242},[247,864,865,868,870,872,874,876,879,881,883,885,887,889,891,894,897,899,902,904],{"class":75,"line":249},[247,866,867],{"class":282},"report ",[247,869,319],{"class":278},[247,871,744],{"class":282},[247,873,747],{"class":527},[247,875,319],{"class":278},[247,877,878],{"class":282},"[",[247,880,755],{"class":278},[247,882,758],{"class":256},[247,884,712],{"class":711},[247,886,763],{"class":282},[247,888,718],{"class":711},[247,890,768],{"class":256},[247,892,893],{"class":278}," for",[247,895,896],{"class":282}," t ",[247,898,478],{"class":278},[247,900,901],{"class":282}," tickets[",[247,903,792],{"class":256},[247,905,906],{"class":282},"]])\n",[247,908,909,912,914,916,918,921,924,926,928,930,932],{"class":75,"line":292},[247,910,911],{"class":282},"report.drop(",[247,913,807],{"class":527},[247,915,319],{"class":278},[247,917,786],{"class":256},[247,919,920],{"class":282},").to_excel(",[247,922,923],{"class":256},"\"attached_links.xlsx\"",[247,925,337],{"class":282},[247,927,528],{"class":527},[247,929,319],{"class":278},[247,931,533],{"class":430},[247,933,546],{"class":282},[247,935,936],{"class":75,"line":306},[247,937,310],{"emptyLinePlaceholder":309},[247,939,940,943,945,948,950],{"class":75,"line":313},[247,941,942],{"class":282},"wb ",[247,944,319],{"class":278},[247,946,947],{"class":282}," load_workbook(",[247,949,923],{"class":256},[247,951,546],{"class":282},[247,953,954,957,959],{"class":75,"line":325},[247,955,956],{"class":282},"ws ",[247,958,319],{"class":278},[247,960,961],{"class":282}," wb.active\n",[247,963,964,967,969,972,974,976,978,981,984,987,990,992,995],{"class":75,"line":351},[247,965,966],{"class":282},"link_col ",[247,968,319],{"class":278},[247,970,971],{"class":282}," [c.value ",[247,973,472],{"class":278},[247,975,475],{"class":282},[247,977,478],{"class":278},[247,979,980],{"class":282}," ws[",[247,982,983],{"class":430},"1",[247,985,986],{"class":282},"]].index(",[247,988,989],{"class":256},"\"link\"",[247,991,469],{"class":282},[247,993,994],{"class":278},"+",[247,996,997],{"class":430}," 1\n",[247,999,1000,1002,1005,1007,1010,1012,1014,1017,1020,1022,1024],{"class":75,"line":374},[247,1001,472],{"class":278},[247,1003,1004],{"class":282}," row, url ",[247,1006,478],{"class":278},[247,1008,1009],{"class":430}," enumerate",[247,1011,783],{"class":282},[247,1013,786],{"class":256},[247,1015,1016],{"class":282},"], ",[247,1018,1019],{"class":527},"start",[247,1021,319],{"class":278},[247,1023,431],{"class":430},[247,1025,434],{"class":282},[247,1027,1028,1031,1033,1036,1039,1041,1044,1047,1049],{"class":75,"line":388},[247,1029,1030],{"class":282},"    cell ",[247,1032,319],{"class":278},[247,1034,1035],{"class":282}," ws.cell(",[247,1037,1038],{"class":527},"row",[247,1040,319],{"class":278},[247,1042,1043],{"class":282},"row, ",[247,1045,1046],{"class":527},"column",[247,1048,319],{"class":278},[247,1050,1051],{"class":282},"link_col)\n",[247,1053,1054,1057,1059],{"class":75,"line":396},[247,1055,1056],{"class":282},"    cell.hyperlink ",[247,1058,319],{"class":278},[247,1060,1061],{"class":282}," url\n",[247,1063,1064,1067,1069],{"class":75,"line":404},[247,1065,1066],{"class":282},"    cell.style ",[247,1068,319],{"class":278},[247,1070,1071],{"class":256}," \"Hyperlink\"\n",[247,1073,1074,1077,1079],{"class":75,"line":410},[247,1075,1076],{"class":282},"wb.save(",[247,1078,923],{"class":256},[247,1080,546],{"class":282},[247,1082,1083,1085,1087,1089,1091,1093],{"class":75,"line":415},[247,1084,551],{"class":430},[247,1086,554],{"class":282},[247,1088,923],{"class":256},[247,1090,842],{"class":282},[247,1092,431],{"class":430},[247,1094,847],{"class":282},[247,1096,1097],{"class":75,"line":437},[247,1098,1099],{"class":564},"# ('Open T-101', 'https:\u002F\u002Fsupport.example.com\u002Ft\u002F101')\n",[10,1101,1102,1103,1106,1107,1110,1111,1115],{},"Iterating over ",[244,1104,1105],{},"tickets[\"url\"]"," in the same order as the rows were written keeps text and links aligned; if you sort or filter before writing, sort the URL column the same way, or keep it in the DataFrame and read it from there. Reading the file back with openpyxl, ",[244,1108,1109],{},"cell.hyperlink.target"," returns the URL — ",[14,1112,1114],{"href":1113},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fextract-hyperlink-urls-from-excel-cells\u002F","Extract Hyperlink URLs from Excel Cells with openpyxl"," covers the reverse direction.",[20,1117,29,1123,29,1126,29,1129,29,1134,29,1138,29,1146,29,1150,29,1156,29,1160,29,1163,29,1167,29,1171,29,1175,29,1178,29,1180,29,1184,29,1186,29,1189,29,1191,29,1193,29,1196,29,1199,29,1201,29,1205,29,1207,29,1210,29,1212,29,1216,29,1219,29,1223,29,1225,29,1228,29,1230,29,1233,29,1235,29,1238,29,1241,29,1244,29,1246,29,1249,29,1251,29,1254,29,1256,29,1259,29,1264,29,1269,29,1276,29,1282,29,1288,29,1293],{"viewBox":1118,"role":23,"ariaLabelledBy":1119,"xmlns":27,"style":1122},"123 0 514 200",[1120,1121],"lnk-result-t","lnk-result-d","width:100%;max-width:514px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[31,1124,1125],{"id":1120},"The finished ticket sheet with attached links",[35,1127,1128],{"id":1121},"A worksheet with ticket, status and link columns. The link column shows Open T-101, Open T-102 and Open T-103 in hyperlink style; each cell's link points to that ticket's URL while the cell value stays plain text.",[39,1130],{"x":1131,"y":42,"width":1132,"height":1133,"fill":45},"123","514","200",[68,1135,1137],{"x":138,"y":1136,"style":72},"31.0","attached_links.xlsx",[39,1139],{"x":1140,"y":1141,"width":1142,"height":1143,"rx":42,"fill":1144,"stroke":1145,"style":80},"139.0","48.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)",[39,1147],{"x":1148,"y":1141,"width":1149,"height":1143,"rx":42,"fill":1144,"stroke":1145,"style":80},"171.0","60.4",[68,1151,1155],{"x":1152,"y":1153,"style":1154},"201.2","65.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[39,1157],{"x":1158,"y":1141,"width":1159,"height":1143,"rx":42,"fill":1144,"stroke":1145,"style":80},"231.4","69.3",[68,1161,1162],{"x":126,"y":1153,"style":1154},"B",[39,1164],{"x":1165,"y":1141,"width":1166,"height":1143,"rx":42,"fill":1144,"stroke":1145,"style":80},"300.7","96.4",[68,1168,1170],{"x":1169,"y":1153,"style":1154},"348.8","C",[39,1172],{"x":1140,"y":1173,"width":1142,"height":1174,"rx":42,"fill":1144,"stroke":1145,"style":80},"72.0","28.0",[68,1176,983],{"x":1177,"y":78,"style":1154},"155.0",[39,1179],{"x":1148,"y":1173,"width":1149,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1181,1183],{"x":1152,"y":78,"style":1182},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","ticket",[39,1185],{"x":1158,"y":1173,"width":1159,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1187,1188],{"x":126,"y":78,"style":1182},"status",[39,1190],{"x":1165,"y":1173,"width":1166,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1192,747],{"x":1169,"y":78,"style":1182},[39,1194],{"x":1140,"y":1195,"width":1142,"height":1174,"rx":42,"fill":1144,"stroke":1145,"style":80},"100.0",[68,1197,431],{"x":1177,"y":1198,"style":1154},"119.0",[39,1200],{"x":1148,"y":1195,"width":1149,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1202,1204],{"x":1152,"y":1198,"style":1203},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","T-101",[39,1206],{"x":1158,"y":1195,"width":1159,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1208,1209],{"x":126,"y":1198,"style":1203},"open",[39,1211],{"x":1165,"y":1195,"width":1166,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1213,1215],{"x":1169,"y":1198,"style":1214},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Open T-101",[39,1217],{"x":1140,"y":1218,"width":1142,"height":1174,"rx":42,"fill":1144,"stroke":1145,"style":80},"128.0",[68,1220,1222],{"x":1177,"y":1221,"style":1154},"147.0","3",[39,1224],{"x":1148,"y":1218,"width":1149,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1226,1227],{"x":1152,"y":1221,"style":1203},"T-102",[39,1229],{"x":1158,"y":1218,"width":1159,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1231,1232],{"x":126,"y":1221,"style":1203},"waiting",[39,1234],{"x":1165,"y":1218,"width":1166,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1236,1237],{"x":1169,"y":1221,"style":1214},"Open T-102",[39,1239],{"x":1140,"y":1240,"width":1142,"height":1174,"rx":42,"fill":1144,"stroke":1145,"style":80},"156.0",[68,1242,41],{"x":1177,"y":1243,"style":1154},"175.0",[39,1245],{"x":1148,"y":1240,"width":1149,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1247,1248],{"x":1152,"y":1243,"style":1203},"T-103",[39,1250],{"x":1158,"y":1240,"width":1159,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1252,1253],{"x":126,"y":1243,"style":1203},"closed",[39,1255],{"x":1165,"y":1240,"width":1166,"height":1174,"rx":42,"fill":45,"stroke":1145,"style":80},[68,1257,1258],{"x":1169,"y":1243,"style":1214},"Open T-103",[75,1260],{"x1":1261,"y1":1262,"x2":1263,"y2":1262,"stroke":54,"style":55},"405.0","116.0","437.0",[1265,1266],"polygon",{"points":1267,"fill":1268},"441.0,116.0 432.0,121.0 432.0,111.0","#5b5cf0",[39,1270],{"x":1271,"y":1272,"width":1273,"height":1274,"rx":1275,"fill":181,"stroke":93,"style":55},"447.0","60.8","174.0","110.5","12",[57,1277,1279],{"transform":1278},"translate(522.0,73.8) scale(1.000)",[61,1280],{"d":187,"fill":64,"stroke":188,"style":1281},"stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[68,1283,1287],{"x":1284,"y":1285,"style":1286},"534.0","120.2","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","cell.hyperlink = url",[68,1289,1292],{"x":1284,"y":1290,"style":1291},"139.8","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","value stays \"Open T-101\"",[68,1294,1296],{"x":1284,"y":1295,"style":1291},"157.2","style = \"Hyperlink\"",[10,1298,1299],{},"Which method to use comes down to three questions: must the display text differ from the URL, will anyone read the file back with code, and which engine does the job already use? The answers usually point at one method clearly:",[20,1301,29,1306,29,1309,29,1312,29,1315,29,1320,29,1325,29,1329,29,1333,29,1337,29,1340,29,1343,29,1351,29,1356,29,1361,29,1366,29,1370,29,1374,29,1376,29,1379,29,1383,29,1386,29,1389,29,1394,29,1398,29,1400,29,1402,29,1405,29,1409,29,1412,29,1415,29,1420,29,1423],{"viewBox":1302,"role":23,"ariaLabelledBy":1303,"xmlns":27,"style":28},"4 0 752 272",[1304,1305],"lnk-choose-t","lnk-choose-d",[31,1307,1308],{"id":1304},"Choosing how to write links",[35,1310,1311],{"id":1305},"A decision chart. If showing the raw URL is fine and the job uses the xlsxwriter engine, rely on automatic detection. If friendly text is needed and URLs are short, HYPERLINK formulas work with either engine. If the file will be read back by code, or links go to other sheets, attach links with openpyxl after writing.",[39,1313],{"x":41,"y":42,"width":43,"height":1314,"fill":45},"272",[39,1316],{"x":1317,"y":49,"width":1318,"height":1319,"rx":1275,"fill":53,"stroke":54,"style":55},"240.0","280.0","75.5",[57,1321,1323],{"transform":1322},"translate(368.0,29.0) scale(1.000)",[61,1324],{"d":187,"fill":64,"stroke":65,"style":1281},[68,1326,1328],{"x":138,"y":1319,"style":1327},"font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","What must the link column do?",[75,1330],{"x1":138,"y1":1331,"x2":138,"y2":1332,"stroke":54,"style":55},"91.5","111.5",[75,1334],{"x1":1335,"y1":1332,"x2":1336,"y2":1332,"stroke":54,"style":55},"134.7","625.3",[75,1338],{"x1":1335,"y1":1332,"x2":1335,"y2":1339,"stroke":54,"style":55},"157.5",[1265,1341],{"points":1342,"fill":1268},"134.7,161.5 129.7,152.5 139.7,152.5",[39,1344],{"x":1345,"y":1346,"width":1347,"height":1348,"rx":1349,"fill":45,"stroke":1145,"style":1350},"82.1","121.5","105.2","21.0","10","stroke-width:1.2px",[68,1352,1355],{"x":1335,"y":1353,"style":1354},"136.0","font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","raw URL is fine",[39,1357],{"x":48,"y":1358,"width":1359,"height":1360,"rx":1275,"fill":53,"stroke":54,"style":55},"163.5","229.3","93.0",[57,1362,1364],{"transform":1363},"translate(122.7,176.5) scale(1.000)",[61,1365],{"d":63,"fill":64,"stroke":65,"style":1281},[68,1367,1369],{"x":1335,"y":1368,"style":1327},"223.0","Automatic detection",[68,1371,1373],{"x":1335,"y":1372,"style":1291},"242.5","xlsxwriter engine",[75,1375],{"x1":138,"y1":1332,"x2":138,"y2":1339,"stroke":54,"style":55},[1265,1377],{"points":1378,"fill":1268},"380.0,161.5 375.0,152.5 385.0,152.5",[39,1380],{"x":1381,"y":1346,"width":1382,"height":1348,"rx":1349,"fill":45,"stroke":1145,"style":1350},"299.6","160.9",[68,1384,1385],{"x":138,"y":1353,"style":1354},"friendly text, short URLs",[39,1387],{"x":1388,"y":1358,"width":1359,"height":1360,"rx":1275,"fill":127,"stroke":128,"style":55},"265.3",[57,1390,1392],{"transform":1391},"translate(368.0,176.5) scale(1.000)",[61,1393],{"d":134,"fill":64,"stroke":135,"style":1281},[68,1395,1397],{"x":138,"y":1368,"style":1396},"font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","HYPERLINK formulas",[68,1399,156],{"x":138,"y":1372,"style":1291},[75,1401],{"x1":1336,"y1":1332,"x2":1336,"y2":1339,"stroke":54,"style":55},[1265,1403],{"points":1404,"fill":1268},"625.3,161.5 620.3,152.5 630.3,152.5",[39,1406],{"x":1407,"y":1346,"width":1408,"height":1348,"rx":1349,"fill":45,"stroke":1145,"style":1350},"555.6","139.5",[68,1410,1411],{"x":1336,"y":1353,"style":1354},"read back or internal",[39,1413],{"x":1414,"y":1358,"width":1359,"height":1360,"rx":1275,"fill":181,"stroke":93,"style":55},"510.7",[57,1416,1418],{"transform":1417},"translate(613.3,176.5) scale(1.000)",[61,1419],{"d":92,"fill":64,"stroke":188,"style":1281},[68,1421,1422],{"x":1336,"y":1368,"style":1286},"Attach with openpyxl",[68,1424,1425],{"x":1336,"y":1372,"style":1291},"cell.hyperlink + \"Hyperlink\" style",[10,1427,1428],{},"A report that is both read by people and processed by another script later — a weekly export that a reconciliation job picks up, for instance — is the case where the choice matters most. Attached links keep the cell's value clean for the script and the link intact for the people.",[232,1430,1432],{"id":1431},"step-4-link-to-other-sheets-in-the-same-workbook","Step 4 — Link to other sheets in the same workbook",[10,1434,1435,1436,1439,1440,1443],{},"The same ",[244,1437,1438],{},"hyperlink"," attribute takes an internal location: a ",[244,1441,1442],{},"#"," followed by a sheet and cell reference. This is how a summary row links to its detail sheet. Quote the sheet name, because names with spaces need it:",[237,1445,1447],{"className":269,"code":1446,"language":271,"meta":242,"style":242},"with pd.ExcelWriter(\"internal_links.xlsx\") as writer:\n    tickets[[\"ticket\", \"status\"]].to_excel(writer, sheet_name=\"Summary\", index=False)\n    for t in tickets[\"ticket\"]:\n        pd.DataFrame({\"ticket\": [t], \"history\": [\"created\"]}).to_excel(writer, sheet_name=f\"Ticket {t}\", index=False)\n\nwb = load_workbook(\"internal_links.xlsx\")\nws = wb[\"Summary\"]\nfor row in range(2, ws.max_row + 1):\n    cell = ws.cell(row=row, column=1)\n    cell.hyperlink = f\"#'Ticket {cell.value}'!A1\"\n    cell.style = \"Hyperlink\"\nwb.save(\"internal_links.xlsx\")\nprint(wb[\"Summary\"][\"A2\"].hyperlink.location or wb[\"Summary\"][\"A2\"].hyperlink.target)\n",[244,1448,1449,1467,1500,1516,1564,1568,1580,1594,1621,1643,1664,1672,1680],{"__ignoreMap":242},[247,1450,1451,1454,1457,1460,1462,1464],{"class":75,"line":249},[247,1452,1453],{"class":278},"with",[247,1455,1456],{"class":282}," pd.ExcelWriter(",[247,1458,1459],{"class":256},"\"internal_links.xlsx\"",[247,1461,469],{"class":282},[247,1463,286],{"class":278},[247,1465,1466],{"class":282}," writer:\n",[247,1468,1469,1472,1474,1476,1479,1482,1485,1487,1490,1492,1494,1496,1498],{"class":75,"line":292},[247,1470,1471],{"class":282},"    tickets[[",[247,1473,792],{"class":256},[247,1475,337],{"class":282},[247,1477,1478],{"class":256},"\"status\"",[247,1480,1481],{"class":282},"]].to_excel(writer, ",[247,1483,1484],{"class":527},"sheet_name",[247,1486,319],{"class":278},[247,1488,1489],{"class":256},"\"Summary\"",[247,1491,337],{"class":282},[247,1493,528],{"class":527},[247,1495,319],{"class":278},[247,1497,533],{"class":430},[247,1499,546],{"class":282},[247,1501,1502,1505,1507,1509,1511,1513],{"class":75,"line":306},[247,1503,1504],{"class":278},"    for",[247,1506,896],{"class":282},[247,1508,478],{"class":278},[247,1510,901],{"class":282},[247,1512,792],{"class":256},[247,1514,1515],{"class":282},"]:\n",[247,1517,1518,1521,1523,1526,1529,1531,1534,1537,1539,1541,1543,1546,1548,1550,1552,1554,1556,1558,1560,1562],{"class":75,"line":313},[247,1519,1520],{"class":282},"        pd.DataFrame({",[247,1522,792],{"class":256},[247,1524,1525],{"class":282},": [t], ",[247,1527,1528],{"class":256},"\"history\"",[247,1530,331],{"class":282},[247,1532,1533],{"class":256},"\"created\"",[247,1535,1536],{"class":282},"]}).to_excel(writer, ",[247,1538,1484],{"class":527},[247,1540,319],{"class":278},[247,1542,755],{"class":278},[247,1544,1545],{"class":256},"\"Ticket ",[247,1547,712],{"class":711},[247,1549,763],{"class":282},[247,1551,718],{"class":711},[247,1553,768],{"class":256},[247,1555,337],{"class":282},[247,1557,528],{"class":527},[247,1559,319],{"class":278},[247,1561,533],{"class":430},[247,1563,546],{"class":282},[247,1565,1566],{"class":75,"line":325},[247,1567,310],{"emptyLinePlaceholder":309},[247,1569,1570,1572,1574,1576,1578],{"class":75,"line":351},[247,1571,942],{"class":282},[247,1573,319],{"class":278},[247,1575,947],{"class":282},[247,1577,1459],{"class":256},[247,1579,546],{"class":282},[247,1581,1582,1584,1586,1589,1591],{"class":75,"line":374},[247,1583,956],{"class":282},[247,1585,319],{"class":278},[247,1587,1588],{"class":282}," wb[",[247,1590,1489],{"class":256},[247,1592,1593],{"class":282},"]\n",[247,1595,1596,1598,1601,1603,1606,1609,1611,1614,1616,1619],{"class":75,"line":388},[247,1597,472],{"class":278},[247,1599,1600],{"class":282}," row ",[247,1602,478],{"class":278},[247,1604,1605],{"class":430}," range",[247,1607,1608],{"class":282},"(",[247,1610,431],{"class":430},[247,1612,1613],{"class":282},", ws.max_row ",[247,1615,994],{"class":278},[247,1617,1618],{"class":430}," 1",[247,1620,434],{"class":282},[247,1622,1623,1625,1627,1629,1631,1633,1635,1637,1639,1641],{"class":75,"line":396},[247,1624,1030],{"class":282},[247,1626,319],{"class":278},[247,1628,1035],{"class":282},[247,1630,1038],{"class":527},[247,1632,319],{"class":278},[247,1634,1043],{"class":282},[247,1636,1046],{"class":527},[247,1638,319],{"class":278},[247,1640,983],{"class":430},[247,1642,546],{"class":282},[247,1644,1645,1647,1649,1651,1654,1656,1659,1661],{"class":75,"line":404},[247,1646,1056],{"class":282},[247,1648,319],{"class":278},[247,1650,705],{"class":278},[247,1652,1653],{"class":256},"\"#'Ticket ",[247,1655,712],{"class":711},[247,1657,1658],{"class":282},"cell.value",[247,1660,718],{"class":711},[247,1662,1663],{"class":256},"'!A1\"\n",[247,1665,1666,1668,1670],{"class":75,"line":410},[247,1667,1066],{"class":282},[247,1669,319],{"class":278},[247,1671,1071],{"class":256},[247,1673,1674,1676,1678],{"class":75,"line":415},[247,1675,1076],{"class":282},[247,1677,1459],{"class":256},[247,1679,546],{"class":282},[247,1681,1682,1684,1687,1689,1692,1695,1698,1701,1703,1705,1707,1709],{"class":75,"line":437},[247,1683,551],{"class":430},[247,1685,1686],{"class":282},"(wb[",[247,1688,1489],{"class":256},[247,1690,1691],{"class":282},"][",[247,1693,1694],{"class":256},"\"A2\"",[247,1696,1697],{"class":282},"].hyperlink.location ",[247,1699,1700],{"class":278},"or",[247,1702,1588],{"class":282},[247,1704,1489],{"class":256},[247,1706,1691],{"class":282},[247,1708,1694],{"class":256},[247,1710,1711],{"class":282},"].hyperlink.target)\n",[10,1713,1714,1718],{},[14,1715,1717],{"href":1716},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-table-of-contents-sheet-with-hyperlinks-in-excel\u002F","Add a Table of Contents Sheet with Hyperlinks in Excel"," builds a full navigation sheet from this pattern.",[232,1720,1722],{"id":1721},"step-5-plan-for-the-two-limits-that-lose-data","Step 5 — Plan for the two limits that lose data",[10,1724,1725,1729,1730,1733],{},[1726,1727,1728],"strong",{},"URL length."," Excel limits a hyperlink to 2,079 characters. xlsxwriter enforces this by warning and ",[615,1731,1732],{},"leaving the cell empty",":",[237,1735,1737],{"className":269,"code":1736,"language":271,"meta":242,"style":242},"import warnings\n\nlong_url = \"https:\u002F\u002Fexample.com\u002Fsearch?q=\" + \"x\" * 2100\nwith warnings.catch_warnings(record=True) as caught:\n    warnings.simplefilter(\"always\")\n    pd.DataFrame({\"url\": [long_url]}).to_excel(\"long.xlsx\", index=False, engine=\"xlsxwriter\")\nprint(len(caught), load_workbook(\"long.xlsx\").active[\"A2\"].value)\n# 1 None\n",[244,1738,1739,1746,1750,1772,1794,1804,1835,1857],{"__ignoreMap":242},[247,1740,1741,1743],{"class":75,"line":249},[247,1742,279],{"class":278},[247,1744,1745],{"class":282}," warnings\n",[247,1747,1748],{"class":75,"line":292},[247,1749,310],{"emptyLinePlaceholder":309},[247,1751,1752,1755,1757,1760,1763,1766,1769],{"class":75,"line":306},[247,1753,1754],{"class":282},"long_url ",[247,1756,319],{"class":278},[247,1758,1759],{"class":256}," \"https:\u002F\u002Fexample.com\u002Fsearch?q=\"",[247,1761,1762],{"class":278}," +",[247,1764,1765],{"class":256}," \"x\"",[247,1767,1768],{"class":278}," *",[247,1770,1771],{"class":430}," 2100\n",[247,1773,1774,1776,1779,1782,1784,1787,1789,1791],{"class":75,"line":313},[247,1775,1453],{"class":278},[247,1777,1778],{"class":282}," warnings.catch_warnings(",[247,1780,1781],{"class":527},"record",[247,1783,319],{"class":278},[247,1785,1786],{"class":430},"True",[247,1788,469],{"class":282},[247,1790,286],{"class":278},[247,1792,1793],{"class":282}," caught:\n",[247,1795,1796,1799,1802],{"class":75,"line":325},[247,1797,1798],{"class":282},"    warnings.simplefilter(",[247,1800,1801],{"class":256},"\"always\"",[247,1803,546],{"class":282},[247,1805,1806,1809,1811,1814,1817,1819,1821,1823,1825,1827,1829,1831,1833],{"class":75,"line":351},[247,1807,1808],{"class":282},"    pd.DataFrame({",[247,1810,786],{"class":256},[247,1812,1813],{"class":282},": [long_url]}).to_excel(",[247,1815,1816],{"class":256},"\"long.xlsx\"",[247,1818,337],{"class":282},[247,1820,528],{"class":527},[247,1822,319],{"class":278},[247,1824,533],{"class":430},[247,1826,337],{"class":282},[247,1828,538],{"class":527},[247,1830,319],{"class":278},[247,1832,543],{"class":256},[247,1834,546],{"class":282},[247,1836,1837,1839,1841,1844,1847,1849,1852,1854],{"class":75,"line":374},[247,1838,551],{"class":430},[247,1840,1608],{"class":282},[247,1842,1843],{"class":430},"len",[247,1845,1846],{"class":282},"(caught), load_workbook(",[247,1848,1816],{"class":256},[247,1850,1851],{"class":282},").active[",[247,1853,1694],{"class":256},[247,1855,1856],{"class":282},"].value)\n",[247,1858,1859],{"class":75,"line":388},[247,1860,1861],{"class":564},"# 1 None\n",[10,1863,1864,1865,1868],{},"The warning scrolls past in a job log and the value is gone. Check lengths before writing, and write over-long URLs as plain text (with ",[244,1866,1867],{},"strings_to_urls"," off) or shorten them:",[237,1870,1872],{"className":269,"code":1871,"language":271,"meta":242,"style":242},"too_long = tickets[\"url\"].str.len() > 2079\nprint(too_long.sum(), \"URL(s) exceed Excel's limit\")\n",[244,1873,1874,1894],{"__ignoreMap":242},[247,1875,1876,1879,1881,1883,1885,1888,1891],{"class":75,"line":249},[247,1877,1878],{"class":282},"too_long ",[247,1880,319],{"class":278},[247,1882,901],{"class":282},[247,1884,786],{"class":256},[247,1886,1887],{"class":282},"].str.len() ",[247,1889,1890],{"class":278},">",[247,1892,1893],{"class":430}," 2079\n",[247,1895,1896,1898,1901,1904],{"class":75,"line":292},[247,1897,551],{"class":430},[247,1899,1900],{"class":282},"(too_long.sum(), ",[247,1902,1903],{"class":256},"\"URL(s) exceed Excel's limit\"",[247,1905,546],{"class":282},[10,1907,1908,1911,1912,1914,1915,1918],{},[1726,1909,1910],{},"Formula injection."," Because both engines write strings beginning with ",[244,1913,319],{}," as formulas, a value typed by a user — a ticket title of ",[244,1916,1917],{},"=HYPERLINK(\"http:\u002F\u002Fevil.example\",\"Click\")"," — becomes a live formula in your report. For columns that hold user-supplied text, stop xlsxwriter from interpreting them:",[237,1920,1922],{"className":269,"code":1921,"language":271,"meta":242,"style":242},"titles = pd.DataFrame({\"title\": [\"Printer jam\", '=HYPERLINK(\"http:\u002F\u002Fevil.example\",\"Click\")']})\nwith pd.ExcelWriter(\"safe.xlsx\", engine=\"xlsxwriter\",\n                    engine_kwargs={\"options\": {\"strings_to_formulas\": False}}) as writer:\n    titles.to_excel(writer, index=False)\nprint(load_workbook(\"safe.xlsx\").active[\"A3\"].data_type)\n# 's' — stored as text\n",[244,1923,1924,1950,1969,1999,2012,2029],{"__ignoreMap":242},[247,1925,1926,1929,1931,1934,1937,1939,1942,1944,1947],{"class":75,"line":249},[247,1927,1928],{"class":282},"titles ",[247,1930,319],{"class":278},[247,1932,1933],{"class":282}," pd.DataFrame({",[247,1935,1936],{"class":256},"\"title\"",[247,1938,331],{"class":282},[247,1940,1941],{"class":256},"\"Printer jam\"",[247,1943,337],{"class":282},[247,1945,1946],{"class":256},"'=HYPERLINK(\"http:\u002F\u002Fevil.example\",\"Click\")'",[247,1948,1949],{"class":282},"]})\n",[247,1951,1952,1954,1956,1959,1961,1963,1965,1967],{"class":75,"line":292},[247,1953,1453],{"class":278},[247,1955,1456],{"class":282},[247,1957,1958],{"class":256},"\"safe.xlsx\"",[247,1960,337],{"class":282},[247,1962,538],{"class":527},[247,1964,319],{"class":278},[247,1966,543],{"class":256},[247,1968,385],{"class":282},[247,1970,1971,1974,1976,1978,1981,1984,1987,1990,1992,1995,1997],{"class":75,"line":306},[247,1972,1973],{"class":527},"                    engine_kwargs",[247,1975,319],{"class":278},[247,1977,712],{"class":282},[247,1979,1980],{"class":256},"\"options\"",[247,1982,1983],{"class":282},": {",[247,1985,1986],{"class":256},"\"strings_to_formulas\"",[247,1988,1989],{"class":282},": ",[247,1991,533],{"class":430},[247,1993,1994],{"class":282},"}}) ",[247,1996,286],{"class":278},[247,1998,1466],{"class":282},[247,2000,2001,2004,2006,2008,2010],{"class":75,"line":313},[247,2002,2003],{"class":282},"    titles.to_excel(writer, ",[247,2005,528],{"class":527},[247,2007,319],{"class":278},[247,2009,533],{"class":430},[247,2011,546],{"class":282},[247,2013,2014,2016,2019,2021,2023,2026],{"class":75,"line":325},[247,2015,551],{"class":430},[247,2017,2018],{"class":282},"(load_workbook(",[247,2020,1958],{"class":256},[247,2022,1851],{"class":282},[247,2024,2025],{"class":256},"\"A3\"",[247,2027,2028],{"class":282},"].data_type)\n",[247,2030,2031],{"class":75,"line":351},[247,2032,2033],{"class":564},"# 's' — stored as text\n",[10,2035,2036,2037,2040],{},"openpyxl has no such switch, but you can force a cell to be text after assigning it: setting ",[244,2038,2039],{},"data_type = \"s\""," stores the value as a string, formula-looking or not.",[237,2042,2044],{"className":269,"code":2043,"language":271,"meta":242,"style":242},"from openpyxl import Workbook\n\nwb = Workbook()\nws = wb.active\nfor row, title in enumerate(titles[\"title\"], start=1):\n    cell = ws.cell(row=row, column=1, value=title)\n    if isinstance(title, str) and title.startswith(\"=\"):\n        cell.data_type = \"s\"\nwb.save(\"safe_openpyxl.xlsx\")\nprint(load_workbook(\"safe_openpyxl.xlsx\").active[\"A2\"].data_type)\n# 's'\n",[244,2045,2046,2057,2061,2070,2078,2104,2134,2161,2171,2180,2194],{"__ignoreMap":242},[247,2047,2048,2050,2052,2054],{"class":75,"line":249},[247,2049,295],{"class":278},[247,2051,298],{"class":282},[247,2053,279],{"class":278},[247,2055,2056],{"class":282}," Workbook\n",[247,2058,2059],{"class":75,"line":292},[247,2060,310],{"emptyLinePlaceholder":309},[247,2062,2063,2065,2067],{"class":75,"line":306},[247,2064,942],{"class":282},[247,2066,319],{"class":278},[247,2068,2069],{"class":282}," Workbook()\n",[247,2071,2072,2074,2076],{"class":75,"line":313},[247,2073,956],{"class":282},[247,2075,319],{"class":278},[247,2077,961],{"class":282},[247,2079,2080,2082,2085,2087,2089,2092,2094,2096,2098,2100,2102],{"class":75,"line":325},[247,2081,472],{"class":278},[247,2083,2084],{"class":282}," row, title ",[247,2086,478],{"class":278},[247,2088,1009],{"class":430},[247,2090,2091],{"class":282},"(titles[",[247,2093,1936],{"class":256},[247,2095,1016],{"class":282},[247,2097,1019],{"class":527},[247,2099,319],{"class":278},[247,2101,983],{"class":430},[247,2103,434],{"class":282},[247,2105,2106,2108,2110,2112,2114,2116,2118,2120,2122,2124,2126,2129,2131],{"class":75,"line":351},[247,2107,1030],{"class":282},[247,2109,319],{"class":278},[247,2111,1035],{"class":282},[247,2113,1038],{"class":527},[247,2115,319],{"class":278},[247,2117,1043],{"class":282},[247,2119,1046],{"class":527},[247,2121,319],{"class":278},[247,2123,983],{"class":430},[247,2125,337],{"class":282},[247,2127,2128],{"class":527},"value",[247,2130,319],{"class":278},[247,2132,2133],{"class":282},"title)\n",[247,2135,2136,2139,2142,2145,2148,2150,2153,2156,2159],{"class":75,"line":374},[247,2137,2138],{"class":278},"    if",[247,2140,2141],{"class":430}," isinstance",[247,2143,2144],{"class":282},"(title, ",[247,2146,2147],{"class":430},"str",[247,2149,469],{"class":282},[247,2151,2152],{"class":278},"and",[247,2154,2155],{"class":282}," title.startswith(",[247,2157,2158],{"class":256},"\"=\"",[247,2160,434],{"class":282},[247,2162,2163,2166,2168],{"class":75,"line":388},[247,2164,2165],{"class":282},"        cell.data_type ",[247,2167,319],{"class":278},[247,2169,2170],{"class":256}," \"s\"\n",[247,2172,2173,2175,2178],{"class":75,"line":396},[247,2174,1076],{"class":282},[247,2176,2177],{"class":256},"\"safe_openpyxl.xlsx\"",[247,2179,546],{"class":282},[247,2181,2182,2184,2186,2188,2190,2192],{"class":75,"line":404},[247,2183,551],{"class":430},[247,2185,2018],{"class":282},[247,2187,2177],{"class":256},[247,2189,1851],{"class":282},[247,2191,1694],{"class":256},[247,2193,2028],{"class":282},[247,2195,2196],{"class":75,"line":410},[247,2197,2198],{"class":564},"# 's'\n",[10,2200,2201,2202,2204],{},"Write your own ",[244,2203,636],{}," formulas in a separate step, after user text has been neutralised, so the only formulas in the sheet are the ones you meant to create.",[232,2206,2208],{"id":2207},"common-pitfalls","Common pitfalls",[2210,2211,2212,2219,2232,2245,2253],"ul",{},[2213,2214,2215,2218],"li",{},[1726,2216,2217],{},"Expecting links from the openpyxl engine."," It writes URLs as text; attach links yourself or switch engines.",[2213,2220,2221,2224,2225,2228,2229,2231],{},[1726,2222,2223],{},"Losing links when reading back."," ",[244,2226,2227],{},"pd.read_excel"," returns cell values only; a ",[244,2230,636],{}," formula's target or an attached link is not in the DataFrame.",[2213,2233,2234,2224,2237,2240,2241,2244],{},[1726,2235,2236],{},"Unquoted sheet names in internal links.",[244,2238,2239],{},"#Ticket T-101!A1"," fails; ",[244,2242,2243],{},"#'Ticket T-101'!A1"," works.",[2213,2246,2247,2224,2250,2252],{},[1726,2248,2249],{},"Links to local files.",[244,2251,504],{}," paths and network-share links work only for readers who can reach the same path; for a report that is emailed, link to a shared location such as SharePoint or an intranet page instead.",[2213,2254,2255,2258],{},[1726,2256,2257],{},"Mixing URL and text columns."," Keep the URL in the DataFrame until the links are attached, then drop it if readers should not see it.",[232,2260,2262],{"id":2261},"performance-notes","Performance notes",[10,2264,2265],{},"Excel allows at most 65,530 hyperlinks per worksheet, and xlsxwriter warns and writes plain strings past that point. For exports larger than that, link only the rows that matter or split the data across sheets. Attaching links with openpyxl costs roughly the same as any per-cell pass — a second or two per 100,000 cells.",[232,2267,2269],{"id":2268},"conclusion","Conclusion",[10,2271,2272,2273,2276,2277,2280],{},"With the xlsxwriter engine, URL strings become links automatically; with openpyxl they stay text. Use ",[244,2274,2275],{},"=HYPERLINK()"," formulas for friendly text when the URLs are short, attach links with ",[244,2278,2279],{},"cell.hyperlink"," and the \"Hyperlink\" style when you want plain values, any text and internal sheet links, and check URL lengths and turn off formula conversion for user data, because both limits otherwise lose or corrupt data without an error.",[232,2282,2284],{"id":2283},"frequently-asked-questions","Frequently asked questions",[10,2286,2287,2290],{},[1726,2288,2289],{},"Why are my URLs clickable with one engine and plain text with another?","\npandas' xlsxwriter engine writes strings through xlsxwriter's write(), which turns anything that looks like a URL into a hyperlink by default. The openpyxl engine writes the same string as plain text.",[10,2292,2293,2296],{},[1726,2294,2295],{},"How do I show friendly text instead of the full URL?","\nEither write =HYPERLINK(\"url\", \"text\") formulas into the column, or write the text and attach the URL with openpyxl's cell.hyperlink. The second keeps the cell a plain value, which is easier to read back.",[10,2298,2299,2302],{},[1726,2300,2301],{},"What happens to very long URLs?","\nExcel limits hyperlinks to 2,079 characters. xlsxwriter warns and leaves the cell empty for a longer URL, so the value is lost. Check lengths before writing and shorten or store long links as text.",[10,2304,2305,2308],{},[1726,2306,2307],{},"Can user data accidentally become a formula?","\nYes. Both engines write any string starting with = as a formula. For data from users or external systems, turn off strings_to_formulas on the xlsxwriter engine, or prefix such values so they stay text.",[232,2310,2312],{"id":2311},"related","Related",[2210,2314,2315,2321,2328,2335],{},[2213,2316,2317,2318,2320],{},"Up one level: ",[14,2319,17],{"href":16}," — the writer and its engines.",[2213,2322,2323,2327],{},[14,2324,2326],{"href":2325},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fadd-hyperlinks-to-excel-cells-with-python\u002F","Add Hyperlinks to Excel Cells with Python"," — hyperlinks cell by cell with openpyxl.",[2213,2329,2330,2334],{},[14,2331,2333],{"href":2332},"\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"," — why the engines differ.",[2213,2336,2337,2341],{},[14,2338,2340],{"href":2339},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-invalid-worksheet-name-errors\u002F","Fix Invalid Worksheet Name Errors When Writing Excel"," — safe names for the sheets you link to.",[2343,2344,2345],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}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 .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":242,"searchDepth":292,"depth":292,"links":2347},[2348,2349,2350,2351,2352,2353,2354,2355,2356,2357,2358],{"id":234,"depth":292,"text":235},{"id":484,"depth":292,"text":485},{"id":629,"depth":292,"text":630},{"id":853,"depth":292,"text":854},{"id":1431,"depth":292,"text":1432},{"id":1721,"depth":292,"text":1722},{"id":2207,"depth":292,"text":2208},{"id":2261,"depth":292,"text":2262},{"id":2268,"depth":292,"text":2269},{"id":2283,"depth":292,"text":2284},{"id":2311,"depth":292,"text":2312},"2026-09-25","Turn a column of URLs into clickable links when writing a DataFrame to Excel: rely on xlsxwriter's automatic URL detection, write HYPERLINK formulas with friendly text, or set cell.hyperlink with openpyxl. Covers link text, internal sheet links, URL length limits and formula injection.","md",[2363,2365,2367,2369],{"q":2289,"a":2364},"pandas' xlsxwriter engine writes strings through xlsxwriter's write(), which turns anything that looks like a URL into a hyperlink by default. The openpyxl engine writes the same string as plain text.",{"q":2295,"a":2366},"Either write =HYPERLINK(\"url\", \"text\") formulas into the column, or write the text and attach the URL with openpyxl's cell.hyperlink. The second keeps the cell a plain value, which is easier to read back.",{"q":2301,"a":2368},"Excel limits hyperlinks to 2,079 characters. xlsxwriter warns and leaves the cell empty for a longer URL, so the value is lost. Check lengths before writing and shorten or store long links as text.",{"q":2307,"a":2370},"Yes. Both engines write any string starting with = as a formula. For data from users or external systems, turn off strings_to_formulas on the xlsxwriter engine, or prefix such values so they stay text.","write clickable hyperlinks from a dataframe column to excel",null,{"breadcrumb":2374},[2375,2378,2381],{"name":2376,"item":2377},"Home","\u002F",{"name":2379,"item":2380},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":17,"item":16},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-clickable-links-from-a-dataframe-to-excel",{"title":2384,"description":2385},"Write Hyperlinks from a pandas DataFrame to Excel","Make a DataFrame URL column clickable in Excel: xlsxwriter strings_to_urls, =HYPERLINK formulas with display text, openpyxl cell.hyperlink, links to other sheets, the 2,079-character limit and formula injection.","write-clickable-links-from-a-dataframe-to-excel","getting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-clickable-links-from-a-dataframe-to-excel\u002Findex",[2389,2390,2391],"writing-excel","cell-styling","pandas","how-to","-CDzR1SoWH4JDncA9he8E_fRISG-kh0tWxgYik2GvzQ",[2395,2399],{"title":2396,"path":2397,"stem":2398,"children":-1},"Write a MultiIndex DataFrame to Excel with pandas","\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-a-multiindex-dataframe-to-excel","getting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-a-multiindex-dataframe-to-excel\u002Findex",{"title":2400,"path":2401,"stem":2402,"children":-1},"Write Dates Without the Time Part from pandas to Excel","\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-dates-without-time-from-pandas-to-excel","getting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fwrite-dates-without-time-from-pandas-to-excel\u002Findex",[2404,2406],{"path":2405,"title":2379},"\u002Fgetting-started-with-python-excel-automation",{"path":2407,"title":17},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas",[],[2410,2413,2416,2419,2422,2425],{"path":2411,"title":2412,"kind":2392},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fwrite-multiple-dataframes-to-one-excel-file","Write Multiple DataFrames to One Excel File",{"path":2414,"title":2415,"kind":2392},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fwrite-a-formatted-excel-report-with-xlsxwriter","Write a Formatted Excel Report with xlsxwriter",{"path":2417,"title":2418,"kind":2392},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Ffind-and-replace-text-in-excel-with-openpyxl","Find and Replace Text in Excel with openpyxl",{"path":2420,"title":2421,"kind":2392},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Finsert-and-delete-rows-and-columns-with-openpyxl","Insert and Delete Rows and Columns with openpyxl",{"path":2423,"title":2424,"kind":2392},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fopenpyxl-append-data-to-existing-excel-sheet","openpyxl: Append Data to an Existing Excel Sheet",{"path":2426,"title":2427,"kind":2392},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Freorder-columns-to-match-a-template-layout-with-pandas","Reorder Columns to Match a Template Layout with pandas",1790972077825]