From 20e9985326c2baef7a16df98641bbe3624560839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B8ydahl?= Date: Wed, 15 Oct 2025 00:44:06 +0200 Subject: [PATCH] SOLR-17957 Remove the XLSXResponseWriter --- solr/CHANGES.txt | 2 + .../java/org/apache/solr/core/SolrCore.java | 10 - .../extraction/XLSXResponseWriter.java | 345 ------------------ .../query-guide/pages/response-writers.adoc | 23 -- .../pages/major-changes-in-solr-10.adoc | 2 + 5 files changed, 4 insertions(+), 378 deletions(-) delete mode 100644 solr/modules/extraction/src/java/org/apache/solr/handler/extraction/XLSXResponseWriter.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 1337991ee21a..e0a36df3d583 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -98,6 +98,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 bfd1ef68c927..57e7fc528c18 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrCore.java +++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java @@ -3102,16 +3102,6 @@ public PluginBag getResponseWriters() { 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/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 ac8e6c549603..000000000000 --- 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 reqNamesMap = new LinkedHashMap<>(); - LinkedHashMap reqWidthsMap = new LinkedHashMap<>(); - - Iterator 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 xlFields = new LinkedHashMap(); - - public XLSXWriter(Writer writer, SolrQueryRequest req, SolrQueryResponse rsp) { - super(writer, req, rsp); - } - - public void writeResponse( - OutputStream out, - LinkedHashMap colNamesMap, - LinkedHashMap colWidthsMap) - throws IOException { - - Collection 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 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/solr-ref-guide/modules/query-guide/pages/response-writers.adoc b/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc index ac86adbbceb8..b4f29b8e6815 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 * <> * <> * <> -* <> * <> * <> @@ -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.` and `colname.` 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 1fef0319aa55..a53ff77b43ca 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 @@ -143,6 +143,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 `` 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.