This is an automated email from the ASF dual-hosted git repository.

janhoy pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_10x by this push:
     new 4f22e74bf0c SOLR-17957 Remove XLSX Response Writer in v10.0 (#3777)
4f22e74bf0c is described below

commit 4f22e74bf0c97937787ecd78e2b2cfb6d4a34c28
Author: Jan Høydahl <[email protected]>
AuthorDate: Thu Oct 16 14:13:11 2025 +0200

    SOLR-17957 Remove XLSX Response Writer in v10.0 (#3777)
    
    (cherry picked from commit 20bf1a998a20364a4026f223c0a0a4e9b4cc9c9a)
---
 solr/CHANGES.txt                                   |   2 +
 .../src/java/org/apache/solr/core/SolrCore.java    |  10 -
 solr/modules/extraction/build.gradle               |   2 -
 .../handler/extraction/XLSXResponseWriter.java     | 345 -----------------
 .../handler/extraction/TestXLSXResponseWriter.java | 418 ---------------------
 .../query-guide/pages/response-writers.adoc        |  23 --
 .../pages/major-changes-in-solr-10.adoc            |   2 +
 7 files changed, 4 insertions(+), 798 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 25f791b4323..149bf5c9e64 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -123,6 +123,8 @@ Bug Fixes
 Deprecation Removals
 ----------------------
 
+* SOLR-17957: XLSXResponseWriter has been removed. (Jan Høydahl)
+
 * SOLR-16535: The 'jaegertracer-configurator' module is removed. Please use 
'opentelemetry' (janhoy)
 
 * SOLR-16601: Removed deprecated methods on the various Solr Clients. (Eric 
Pugh, Kevin Risden)
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java 
b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index 7ac546aa255..5beca634fe3 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -3097,16 +3097,6 @@ public class SolrCore implements SolrInfoBean, Closeable 
{
     m.put(OPEN_METRICS_WT, new PrometheusResponseWriter());
     m.put(ReplicationAPIBase.FILE_STREAM, getFileStreamWriter());
     DEFAULT_RESPONSE_WRITERS = Collections.unmodifiableMap(m);
-    try {
-      m.put(
-          "xlsx",
-          
Class.forName("org.apache.solr.handler.extraction.XLSXResponseWriter")
-              .asSubclass(QueryResponseWriter.class)
-              .getDeclaredConstructor()
-              .newInstance());
-    } catch (Exception e) {
-      // don't worry; extraction module not in class path
-    }
   }
 
   private static JavaBinResponseWriter getFileStreamWriter() {
diff --git a/solr/modules/extraction/build.gradle 
b/solr/modules/extraction/build.gradle
index da6ebaccd68..655fc0360f4 100644
--- a/solr/modules/extraction/build.gradle
+++ b/solr/modules/extraction/build.gradle
@@ -27,8 +27,6 @@ dependencies {
   implementation libs.apache.lucene.core
   implementation libs.slf4j.api
 
-  implementation libs.apache.poi.poi
-  implementation libs.apache.poi.ooxml
   implementation libs.apache.tika.core
   implementation (libs.apache.tika.parsers, {
     exclude group: 'org.apache.cxf', module: 'cxf-rt-rs-client'
diff --git 
a/solr/modules/extraction/src/java/org/apache/solr/handler/extraction/XLSXResponseWriter.java
 
b/solr/modules/extraction/src/java/org/apache/solr/handler/extraction/XLSXResponseWriter.java
deleted file mode 100644
index ac8e6c54960..00000000000
--- 
a/solr/modules/extraction/src/java/org/apache/solr/handler/extraction/XLSXResponseWriter.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.handler.extraction;
-
-import java.io.CharArrayWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.lucene.index.IndexableField;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.FillPatternType;
-import org.apache.poi.ss.usermodel.Font;
-import org.apache.poi.ss.usermodel.IndexedColors;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.xssf.streaming.SXSSFWorkbook;
-import org.apache.poi.xssf.usermodel.XSSFCellStyle;
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.response.QueryResponseWriter;
-import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.response.TabularResponseWriter;
-import org.apache.solr.schema.FieldType;
-import org.apache.solr.schema.SchemaField;
-import org.apache.solr.schema.StrField;
-import org.apache.solr.search.ReturnFields;
-
-/**
- * A .XLSX spreadsheet format {@link 
org.apache.solr.response.QueryResponseWriter}.
- *
- * @deprecated This class will be removed in a future release.
- */
-@Deprecated(since = "9.10", forRemoval = true)
-public class XLSXResponseWriter implements QueryResponseWriter {
-
-  @Override
-  public void write(
-      OutputStream out, SolrQueryRequest req, SolrQueryResponse rsp, String 
contentType)
-      throws IOException {
-    // throw away arraywriter just to satisfy super requirements; we're 
grabbing
-    // all writes before they go to it anyway
-    XLSXWriter w = new XLSXWriter(new CharArrayWriter(), req, rsp);
-
-    LinkedHashMap<String, String> reqNamesMap = new LinkedHashMap<>();
-    LinkedHashMap<String, Integer> reqWidthsMap = new LinkedHashMap<>();
-
-    Iterator<String> paramNamesIter = 
req.getParams().getParameterNamesIterator();
-    while (paramNamesIter.hasNext()) {
-      String nextParam = paramNamesIter.next();
-      if (nextParam.startsWith("colname.")) {
-        String field = nextParam.substring("colname.".length());
-        reqNamesMap.put(field, req.getParams().get(nextParam));
-      } else if (nextParam.startsWith("colwidth.")) {
-        String field = nextParam.substring("colwidth.".length());
-        reqWidthsMap.put(field, req.getParams().getInt(nextParam));
-      }
-    }
-
-    try {
-      w.writeResponse(out, reqNamesMap, reqWidthsMap);
-    } finally {
-      w.close();
-    }
-  }
-
-  @Override
-  public String getContentType(SolrQueryRequest request, SolrQueryResponse 
response) {
-    return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
-  }
-}
-
-class XLSXWriter extends TabularResponseWriter {
-
-  static class SerialWriteWorkbook {
-    SXSSFWorkbook swb;
-    Sheet sh;
-
-    XSSFCellStyle headerStyle;
-    int rowIndex;
-    Row curRow;
-    int cellIndex;
-
-    SerialWriteWorkbook() {
-      this.swb = new SXSSFWorkbook(100);
-      this.sh = this.swb.createSheet();
-
-      this.rowIndex = 0;
-
-      this.headerStyle = (XSSFCellStyle) swb.createCellStyle();
-      this.headerStyle.setFillBackgroundColor(IndexedColors.BLACK.getIndex());
-      // solid fill
-      this.headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
-      Font headerFont = swb.createFont();
-      headerFont.setFontHeightInPoints((short) 14);
-      headerFont.setBold(true);
-      headerFont.setColor(IndexedColors.WHITE.getIndex());
-      this.headerStyle.setFont(headerFont);
-    }
-
-    void addRow() {
-      curRow = sh.createRow(rowIndex++);
-      cellIndex = 0;
-    }
-
-    void setHeaderRow() {
-      curRow.setHeightInPoints((short) 21);
-    }
-
-    // sets last created cell to have header style
-    void setHeaderCell() {
-      curRow.getCell(cellIndex - 1).setCellStyle(this.headerStyle);
-    }
-
-    // set the width of the most recently created column
-    void setColWidth(int charWidth) {
-      // width in poi is units of 1/256th of a character width for some reason
-      this.sh.setColumnWidth(cellIndex - 1, 256 * charWidth);
-    }
-
-    void writeCell(String value) {
-      Cell cell = curRow.createCell(cellIndex++);
-      cell.setCellValue(value);
-    }
-
-    void flush(OutputStream out) {
-      try {
-        swb.write(out);
-      } catch (IOException e) {
-        StringWriter sw = new StringWriter();
-        e.printStackTrace(new PrintWriter(sw));
-        String stacktrace = sw.toString();
-      } finally {
-        swb.dispose();
-      }
-    }
-  }
-
-  private SerialWriteWorkbook wb = new SerialWriteWorkbook();
-
-  static class XLField {
-    String name;
-    SchemaField sf;
-  }
-
-  private Map<String, XLField> xlFields = new LinkedHashMap<String, XLField>();
-
-  public XLSXWriter(Writer writer, SolrQueryRequest req, SolrQueryResponse 
rsp) {
-    super(writer, req, rsp);
-  }
-
-  public void writeResponse(
-      OutputStream out,
-      LinkedHashMap<String, String> colNamesMap,
-      LinkedHashMap<String, Integer> colWidthsMap)
-      throws IOException {
-
-    Collection<String> fields = getFields();
-    for (String field : fields) {
-      if (!returnFields.wantsField(field)) {
-        continue;
-      }
-      if (field.equals("score")) {
-        XLField xlField = new XLField();
-        xlField.name = "score";
-        xlFields.put("score", xlField);
-        continue;
-      }
-
-      if (shouldSkipField(field)) {
-        continue;
-      }
-      SchemaField sf = schema.getFieldOrNull(field);
-      if (sf == null) {
-        FieldType ft = new StrField();
-        sf = new SchemaField(field, ft);
-      }
-
-      XLField xlField = new XLField();
-      xlField.name = field;
-      xlField.sf = sf;
-      xlFields.put(field, xlField);
-    }
-
-    wb.addRow();
-    // write header
-    for (XLField xlField : xlFields.values()) {
-      String printName = xlField.name;
-      int colWidth = 14;
-
-      String niceName = colNamesMap.get(xlField.name);
-      if (niceName != null) {
-        printName = niceName;
-      }
-
-      Integer niceWidth = colWidthsMap.get(xlField.name);
-      if (niceWidth != null) {
-        colWidth = niceWidth.intValue();
-      }
-
-      writeStr(xlField.name, printName, false);
-      wb.setColWidth(colWidth);
-      wb.setHeaderCell();
-    }
-    wb.setHeaderRow();
-    wb.addRow();
-
-    writeResponse(rsp.getResponse());
-
-    wb.flush(out);
-    wb = null;
-  }
-
-  @Override
-  public void close() throws IOException {
-    super.close();
-  }
-
-  // NOTE: a document cannot currently contain another document
-  List<Object> tmpList;
-
-  @Override
-  public void writeSolrDocument(String name, SolrDocument doc, ReturnFields 
returnFields, int idx)
-      throws IOException {
-    if (tmpList == null) {
-      tmpList = new ArrayList<>(1);
-      tmpList.add(null);
-    }
-
-    for (XLField xlField : xlFields.values()) {
-      Object val = doc.getFieldValue(xlField.name);
-      int nVals = val instanceof Collection ? ((Collection) val).size() : (val 
== null ? 0 : 1);
-      if (nVals == 0) {
-        writeNull(xlField.name);
-        continue;
-      }
-
-      if ((xlField.sf != null && xlField.sf.multiValued()) || nVals > 1) {
-        Collection<?> values;
-        // normalize to a collection
-        if (val instanceof Collection) {
-          values = (Collection<?>) val;
-        } else {
-          tmpList.set(0, val);
-          values = tmpList;
-        }
-
-        writeArray(xlField.name, values.iterator(), false);
-
-      } else {
-        // normalize to first value
-        if (val instanceof Collection<?> values) {
-          val = values.iterator().next();
-        }
-        writeVal(xlField.name, val);
-      }
-    }
-    wb.addRow();
-  }
-
-  @Override
-  public void writeStr(String name, String val, boolean needsEscaping) throws 
IOException {
-    wb.writeCell(val);
-  }
-
-  @Override
-  public void writeArray(String name, Iterator<?> val, boolean raw) throws 
IOException {
-    assert !raw;
-    StringBuilder output = new StringBuilder();
-    while (val.hasNext()) {
-      Object v = val.next();
-      if (v instanceof IndexableField f) {
-        if (v instanceof Date) {
-          output.append(((Date) val).toInstant().toString()).append("; ");
-        } else {
-          output.append(f.stringValue()).append("; ");
-        }
-      } else {
-        output.append(v.toString()).append("; ");
-      }
-    }
-    if (output.length() > 0) {
-      output.deleteCharAt(output.length() - 1);
-      output.deleteCharAt(output.length() - 1);
-    }
-    writeStr(name, output.toString(), false);
-  }
-
-  @Override
-  public void writeNull(String name) throws IOException {
-    wb.writeCell("");
-  }
-
-  @Override
-  public void writeInt(String name, String val) throws IOException {
-    wb.writeCell(val);
-  }
-
-  @Override
-  public void writeLong(String name, String val) throws IOException {
-    wb.writeCell(val);
-  }
-
-  @Override
-  public void writeBool(String name, String val) throws IOException {
-    wb.writeCell(val);
-  }
-
-  @Override
-  public void writeFloat(String name, String val) throws IOException {
-    wb.writeCell(val);
-  }
-
-  @Override
-  public void writeDouble(String name, String val) throws IOException {
-    wb.writeCell(val);
-  }
-
-  @Override
-  public void writeDate(String name, String val) throws IOException {
-    wb.writeCell(val);
-  }
-}
diff --git 
a/solr/modules/extraction/src/test/org/apache/solr/handler/extraction/TestXLSXResponseWriter.java
 
b/solr/modules/extraction/src/test/org/apache/solr/handler/extraction/TestXLSXResponseWriter.java
deleted file mode 100644
index 8eca2b0105c..00000000000
--- 
a/solr/modules/extraction/src/test/org/apache/solr/handler/extraction/TestXLSXResponseWriter.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.handler.extraction;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.time.Instant;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.core.SolrCore;
-import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.response.QueryResponseWriter;
-import org.apache.solr.response.RawResponseWriter;
-import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.search.SolrReturnFields;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class TestXLSXResponseWriter extends SolrTestCaseJ4 {
-
-  private static QueryResponseWriter writerXlsx;
-
-  @BeforeClass
-  public static void beforeClass() throws Exception {
-    System.setProperty("solr.index.updatelog.enabled", "false");
-    initCore("solrconfig.xml", "schema.xml", 
getFile("extraction/solr").toAbsolutePath());
-    createIndex();
-    // find a reference to the default response writer so we can redirect its 
output later
-    SolrCore testCore = h.getCore();
-    QueryResponseWriter writer = testCore.getQueryResponseWriter("xlsx");
-    if (writer != null) {
-      writerXlsx = writer;
-    } else {
-      throw new Exception("XLSXResponseWriter not registered with solr core");
-    }
-  }
-
-  public static void createIndex() {
-    assertU(
-        adoc(
-            "id",
-            "1",
-            "foo_i",
-            "-1",
-            "foo_s",
-            "hi",
-            "foo_l",
-            "12345678987654321",
-            "foo_b",
-            "false",
-            "foo_f",
-            "1.414",
-            "foo_d",
-            "-1.0E300",
-            "foo_dt1",
-            "2000-01-02T03:04:05Z"));
-    assertU(
-        adoc(
-            "id",
-            "2",
-            "v_ss",
-            "hi",
-            "v_ss",
-            "there",
-            "v2_ss",
-            "nice",
-            "v2_ss",
-            "output",
-            "shouldbeunstored",
-            "foo"));
-    assertU(adoc("id", "3", "shouldbeunstored", "foo"));
-    assertU(adoc("id", "4", "foo_s1", "foo"));
-    assertU(adoc("id", "5", "pubyear_ii", "123", "store_iis", "12", 
"price_ff", "1.3"));
-    assertU(commit());
-  }
-
-  @AfterClass
-  public static void cleanupWriter() throws Exception {
-    writerXlsx = null;
-  }
-
-  @Test
-  public void testStructuredDataViaBaseWriters() throws Exception {
-    SolrQueryResponse rsp = new SolrQueryResponse();
-    // Don't send a ContentStream back, this will fall back to the configured 
base writer.
-    // But abuse the CONTENT key to ensure writer is also checking type
-    rsp.add(RawResponseWriter.CONTENT, "test");
-    rsp.add("foo", "bar");
-
-    SolrQueryRequest r = req();
-
-    // check Content-Type
-    assertEquals(
-        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
-        writerXlsx.getContentType(r, rsp));
-
-    // test our basic types,and that fields come back in the requested order
-    XSSFSheet resultSheet =
-        getWSResultForQuery(
-            req("q", "id:1", "wt", "xlsx", "fl", 
"id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt1"));
-
-    assertEquals(
-        
"id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt1\n1,hi,-1,12345678987654321,F,1.414,-1.0E300,2000-01-02T03:04:05Z\n",
-        getStringFromSheet(resultSheet));
-
-    resultSheet = getWSResultForQuery(req("q", "id:1^0", "wt", "xlsx", "fl", 
"id,score,foo_s"));
-    // test retrieving score
-    assertEquals("id,score,foo_s\n1,0.0,hi\n", 
getStringFromSheet(resultSheet));
-
-    resultSheet =
-        getWSResultForQuery(
-            req(
-                "q",
-                "id:1^0",
-                "wt",
-                "xlsx",
-                "colname.id",
-                "I.D.",
-                "colwidth.id",
-                "10",
-                "fl",
-                "id,score,foo_s"));
-    // test override colname/width
-    assertEquals("I.D.,score,foo_s\n1,0.0,hi\n", 
getStringFromSheet(resultSheet));
-    // test colwidth (value returned is in 256ths of a character as per excel 
standard)
-    assertEquals(10 * 256, resultSheet.getColumnWidth(0));
-
-    resultSheet = getWSResultForQuery(req("q", "id:2", "wt", "xlsx", "fl", 
"id,v_ss"));
-    // test multivalued
-    assertEquals("id,v_ss\n2,hi; there\n", getStringFromSheet(resultSheet));
-
-    // test retrieving fields from index
-    resultSheet = getWSResultForQuery(req("q", "*:*", "wt", "xslx", "fl", 
"*,score"));
-    String result = getStringFromSheet(resultSheet);
-    for (String field :
-        
"id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt1,v_ss,v2_ss,score".split(",")) {
-      assertTrue(result.contains(field));
-    }
-
-    // test null values
-    resultSheet = getWSResultForQuery(req("q", "id:2", "wt", "xlsx", "fl", 
"id,foo_s,v_ss"));
-    assertEquals("id,foo_s,v_ss\n2,,hi; there\n", 
getStringFromSheet(resultSheet));
-
-    // now test SolrDocumentList
-    SolrDocument d = new SolrDocument();
-    SolrDocument d1 = d;
-    d.addField("id", "1");
-    d.addField("foo_i", -1);
-    d.addField("foo_s", "hi");
-    d.addField("foo_l", "12345678987654321L");
-    d.addField("foo_b", false);
-    d.addField("foo_f", 1.414f);
-    d.addField("foo_d", -1.0E300);
-    d.addField("foo_dt1", new 
Date(Instant.parse("2000-01-02T03:04:05Z").toEpochMilli()));
-    d.addField("score", "2.718");
-
-    d = new SolrDocument();
-    SolrDocument d2 = d;
-    d.addField("id", "2");
-    d.addField("v_ss", "hi");
-    d.addField("v_ss", "there");
-    d.addField("v2_ss", "nice");
-    d.addField("v2_ss", "output");
-    d.addField("score", "89.83");
-    d.addField("shouldbeunstored", "foo");
-
-    SolrDocumentList sdl = new SolrDocumentList();
-    sdl.add(d1);
-    sdl.add(d2);
-
-    SolrQueryRequest req = req("q", "*:*");
-    rsp = new SolrQueryResponse();
-    rsp.addResponse(sdl);
-
-    rsp.setReturnFields(new SolrReturnFields("id,foo_s", req));
-
-    resultSheet = getWSResultForQuery(req, rsp);
-    assertEquals("id,foo_s\n1,hi\n2,\n", getStringFromSheet(resultSheet));
-
-    // try scores
-    rsp.setReturnFields(new SolrReturnFields("id,score,foo_s", req));
-
-    resultSheet = getWSResultForQuery(req, rsp);
-    assertEquals("id,score,foo_s\n1,2.718,hi\n2,89.83,\n", 
getStringFromSheet(resultSheet));
-
-    // get field values from docs... should be ordered and not include score 
unless requested
-    rsp.setReturnFields(new SolrReturnFields("*", req));
-
-    resultSheet = getWSResultForQuery(req, rsp);
-    assertEquals(
-        "id,foo_i,foo_s,foo_l,foo_b,foo_f,foo_d,foo_dt1,v_ss,v2_ss\n"
-            + 
"1,-1,hi,12345678987654321L,false,1.414,-1.0E300,2000-01-02T03:04:05Z,,\n"
-            + "2,,,,,,,,hi; there,nice; output\n",
-        getStringFromSheet(resultSheet));
-
-    // get field values and scores - just check that the scores are there... 
we don't guarantee
-    // where
-    rsp.setReturnFields(new SolrReturnFields("*,score", req));
-    resultSheet = getWSResultForQuery(req, rsp);
-    String s = getStringFromSheet(resultSheet);
-    assertTrue(s.contains("score") && s.indexOf("2.718") > 0 && 
s.indexOf("89.83") > 0);
-
-    // Test field globs
-    rsp.setReturnFields(new SolrReturnFields("id,foo*", req));
-    resultSheet = getWSResultForQuery(req, rsp);
-    assertEquals(
-        "id,foo_i,foo_s,foo_l,foo_b,foo_f,foo_d,foo_dt1\n"
-            + 
"1,-1,hi,12345678987654321L,false,1.414,-1.0E300,2000-01-02T03:04:05Z\n"
-            + "2,,,,,,,\n",
-        getStringFromSheet(resultSheet));
-
-    rsp.setReturnFields(new SolrReturnFields("id,*_d*", req));
-    resultSheet = getWSResultForQuery(req, rsp);
-    assertEquals(
-        "id,foo_d,foo_dt1\n" + "1,-1.0E300,2000-01-02T03:04:05Z\n" + "2,,\n",
-        getStringFromSheet(resultSheet));
-
-    // Test function queries
-    rsp.setReturnFields(new 
SolrReturnFields("sum(1,1),id,exists(foo_s1),div(9,1),foo_f", req));
-    resultSheet = getWSResultForQuery(req, rsp);
-    assertEquals(
-        "sum(1,1),id,exists(foo_s1),div(9,1),foo_f\n" + ",1,,,1.414\n" + 
",2,,,\n",
-        getStringFromSheet(resultSheet));
-
-    // Test transformers
-    rsp.setReturnFields(new SolrReturnFields("mydocid:[docid],[explain]", 
req));
-    resultSheet = getWSResultForQuery(req, rsp);
-    assertEquals("mydocid,[explain]\n" + ",\n" + ",\n", 
getStringFromSheet(resultSheet));
-
-    req.close();
-  }
-
-  @Test
-  public void testPseudoFields() throws Exception {
-    // Use Pseudo Field
-    SolrQueryRequest req = req("q", "id:1", "wt", "xlsx", "fl", 
"XXX:id,foo_s");
-    XSSFSheet resultSheet = getWSResultForQuery(req);
-    assertEquals("XXX,foo_s\n1,hi\n", getStringFromSheet(resultSheet));
-
-    String txt =
-        getStringFromSheet(
-            getWSResultForQuery(
-                req("q", "id:1", "wt", "xlsx", "fl", 
"XXX:id,YYY:[docid],FOO:foo_s")));
-    String[] lines = txt.split("\n");
-    assertEquals(2, lines.length);
-    assertEquals("XXX,YYY,FOO", lines[0]);
-    assertEquals("1,0,hi", lines[1]);
-
-    // assertions specific to multiple pseudofields functions like abs, div, 
exists, etc..
-    // (SOLR-5423)
-    String funcText =
-        getStringFromSheet(
-            getWSResultForQuery(
-                req("df", "text", "q", "*", "wt", "xlsx", "fl", 
"XXX:id,YYY:exists(foo_s1)")));
-    String[] funcLines = funcText.split("\n");
-    assertEquals(6, funcLines.length);
-    assertEquals("XXX,YYY", funcLines[0]);
-    assertEquals("1,false", funcLines[1]);
-    assertEquals("3,false", funcLines[3]);
-
-    // assertions specific to single function without alias (SOLR-5423)
-    String singleFuncText =
-        getStringFromSheet(
-            getWSResultForQuery(
-                req("df", "text", "q", "*", "wt", "xlsx", "fl", 
"exists(foo_s1),XXX:id")));
-    String[] singleFuncLines = singleFuncText.split("\n");
-    assertEquals(6, singleFuncLines.length);
-    assertEquals("exists(foo_s1),XXX", singleFuncLines[0]);
-    assertEquals("false,1", singleFuncLines[1]);
-    assertEquals("false,3", singleFuncLines[3]);
-
-    // pseudo-fields with * in fl
-    txt =
-        getStringFromSheet(
-            getWSResultForQuery(
-                req("df", "text", "q", "id:4", "wt", "xlsx", "fl", 
"*,YYY:[docid],FOO:foo_s1")));
-    lines = txt.split("\n");
-    assertEquals(2, lines.length);
-    assertEquals(
-        sortHeader(
-            "foo_i,foo_l,FOO,foo_s,pubyear_ii,store_iis,"
-                + 
"v2_ss,multiDefault,timestamp,foo_dt1,foo_b,YYY,foo_d,id,foo_f,v_ss,foo_s1,intDefault"),
-        sortHeader(lines[0]));
-  }
-
-  @Test
-  public void testForDVEnabledFields() throws Exception {
-    // for dv enabled and useDocValueAsStored=true
-    // returns pubyear_ii, store_iis but not price_ff
-    String singleFuncText =
-        getStringFromSheet(getWSResultForQuery(req("df", "text", "q", "id:5", 
"wt", "xlsx")));
-    String sortedHeader =
-        sortHeader(
-            "foo_i,foo_l,foo_s,pubyear_ii,store_iis,"
-                + 
"v2_ss,multiDefault,timestamp,foo_dt1,foo_b,foo_d,id,foo_f,v_ss,foo_s1,intDefault");
-    String[] singleFuncLines = singleFuncText.split("\n");
-    assertEquals(2, singleFuncLines.length);
-    assertEquals(sortedHeader, sortHeader(singleFuncLines[0]));
-    List<String> actualVal =
-        Arrays.stream(singleFuncLines[1].trim().split(","))
-            .filter(val -> !val.trim().isEmpty() && !val.trim().equals("\"\""))
-            .collect(Collectors.toList());
-    assertTrue(actualVal.containsAll(Arrays.asList("5", "123", "12")));
-
-    // explicit fl=*
-    singleFuncText =
-        getStringFromSheet(
-            getWSResultForQuery(req("df", "text", "q", "id:5", "wt", "xlsx", 
"fl", "*")));
-    singleFuncLines = singleFuncText.split("\n");
-    assertEquals(2, singleFuncLines.length);
-    assertEquals(sortedHeader, sortHeader(singleFuncLines[0]));
-    actualVal =
-        Arrays.stream(singleFuncLines[1].trim().split(","))
-            .filter(val -> !val.trim().isEmpty() && !val.trim().equals("\"\""))
-            .collect(Collectors.toList());
-    assertTrue(actualVal.containsAll(Arrays.asList("5", "123", "12")));
-
-    // explicit price_ff
-    singleFuncText =
-        getStringFromSheet(
-            getWSResultForQuery(req("df", "text", "q", "id:5", "wt", "xlsx", 
"fl", "price_ff")));
-    singleFuncLines = singleFuncText.split("\n");
-    assertEquals(2, singleFuncLines.length);
-    assertEquals("price_ff", singleFuncLines[0]);
-    assertEquals("1.3", singleFuncLines[1]);
-
-    // explicit price_ff with fl=*
-    singleFuncText =
-        getStringFromSheet(
-            getWSResultForQuery(
-                req(
-                    "df",
-                    "text",
-                    "q",
-                    "id:5",
-                    "wt",
-                    "xlsx",
-                    "csv.header",
-                    "true",
-                    "fl",
-                    "*,price_ff")));
-    sortedHeader =
-        sortHeader(
-            "foo_i,foo_l,foo_b,foo_s,pubyear_ii,store_iis,"
-                + 
"v2_ss,multiDefault,timestamp,foo_dt1,id,foo_d,foo_f,v_ss,foo_s1,intDefault,price_ff");
-    singleFuncLines = singleFuncText.split("\n");
-    assertEquals(2, singleFuncLines.length);
-    assertEquals(sortedHeader, sortHeader(singleFuncLines[0]));
-    actualVal =
-        Arrays.stream(singleFuncLines[1].trim().split(","))
-            .filter(val -> !val.trim().isEmpty() && !val.trim().equals("\"\""))
-            .collect(Collectors.toList());
-    assertTrue(actualVal.containsAll(Arrays.asList("5", "123", "12", "1.3")));
-  }
-
-  // returns first worksheet as XLSXResponseWriter only returns one sheet
-  private XSSFSheet getWSResultForQuery(SolrQueryRequest req) throws Exception 
{
-    SolrQueryResponse rsp = h.queryAndResponse("", req);
-    return getWSResultForQuery(req, rsp);
-  }
-
-  private XSSFSheet getWSResultForQuery(SolrQueryRequest req, 
SolrQueryResponse rsp)
-      throws Exception {
-    ByteArrayOutputStream xmlBout = new ByteArrayOutputStream();
-    writerXlsx.write(xmlBout, req, rsp);
-    XSSFWorkbook output = new XSSFWorkbook(new 
ByteArrayInputStream(xmlBout.toByteArray()));
-    XSSFSheet sheet = output.getSheetAt(0);
-    req.close();
-    output.close();
-    return sheet;
-  }
-
-  private String getStringFromSheet(XSSFSheet sheet) {
-    StringBuilder output = new StringBuilder();
-    for (Row row : sheet) {
-      for (Cell cell : row) {
-        output.append(cell.getStringCellValue());
-        output.append(",");
-      }
-      output.setLength(output.length() - 1);
-      output.append("\n");
-    }
-    return output.toString();
-  }
-
-  /*
-   * Utility method to sort a comma separated list of strings, for easier 
comparison regardless of platform
-   */
-  private String sortHeader(String input) {
-    String[] output = input.trim().split(",");
-    Arrays.sort(output);
-    return Arrays.toString(output);
-  }
-}
diff --git 
a/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc 
b/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc
index ac86adbbceb..b4f29b8e681 100644
--- a/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc
+++ b/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc
@@ -30,7 +30,6 @@ The list below describe shows the most common settings for 
the `wt` parameter, w
 * <<Binary Response Writer,javabin>>
 * <<JSON Response Writer,json>>
 * <<Smile Response Writer,smile>>
-* <<XLSX Response Writer,xlsx>>
 * <<Standard XML Response Writer,xml>>
 * <<XSLT Response Writer,xslt>>
 
@@ -387,25 +386,3 @@ else:
 == Smile Response Writer
 
 The Smile format is a JSON-compatible binary format, described in detail here: 
https://en.wikipedia.org/wiki/Smile_%28data_interchange_format%29[https://en.wikipedia.org/wiki/Smile_(data_interchange_format)]
-
-== XLSX Response Writer
-
-Use this to get the response as a spreadsheet in the .xlsx (Microsoft Excel) 
format.
-It accepts parameters in the form `colwidth.<field-name>` and 
`colname.<field-name>` which helps you customize the column widths and column 
names.
-
-This response writer has been added as part of the extraction library, and 
will only work if the extraction module is present in the server classpath.
-Defining the classpath with the `lib` directive is not sufficient.
-Instead, you will need to copy the necessary .jars to the Solr webapp's `lib` 
directory manually.
-You can run these commands from your `$SOLR_INSTALL` directory:
-
-[source,bash]
-----
-cp modules/extraction/lib/*.jar server/solr-webapp/webapp/WEB-INF/lib/
-----
-
-Once the libraries are in place, you can add `wt=xlsx` to your request, and 
results will be returned as an XLSX sheet.
-
-[IMPORTANT]
-====
-The `XLSXResponseWriter` is deprecated and will be removed in a future release.
-====
diff --git 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
index 01a86b161b4..bcd10974008 100644
--- 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
+++ 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
@@ -141,6 +141,8 @@ To share resource intensive objects across multiple cores 
in components you shou
 * The language specific Response Writers, which were deprecated in 9.8 in 
favour of more widely used formats like JSON have been removed.
 The removed writer types (invoked as part of the `wt` parameter) include 
`python`, `ruby`, `php`, and `phps`.
 
+* The XLSX Response Writer (`wt=xlsx`), which was deprecated in 9.10, has been 
removed. Users needing Excel export functionality should use CSV format 
(`wt=csv`) and convert it to Excel format using external tools or libraries.
+
 * The deprecated support for configuring replication using master/slave 
terminology is removed.  Use leader/follower.
 
 * Support for the `<lib/>` directive, which historically could be used in 
solrconfig.xml to add JARs on a core-by-core basis, was deprecated in 9.8 and 
has now been removed.

Reply via email to