Джерси @ Продукты Apache XSSFWorkbook
Я пытаюсь создать книгу XSSFWorkbook, используя Джерси.
Я пробовал следующие заголовки и ничего не работает:
@Produces ("приложение / XML")
@Produces ("Применение / vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@Produces ("приложение /vnd.openxml"
Все возвращают следующую ошибку:
Вызывается: com.sun.jersey.api.MessageException: средство записи тела сообщения для класса Java org.apache.poi.xssf.usermodel.XSSFWorkbook и класса Java-типа org.apache.poi.xssf.usermodel.XSSFWorkbook и MIME Тип медиа приложения /xml не найден... еще 37
По сути, у меня есть функция, которая создает XSSFWorkbook, и я хотел бы выписать ее для загрузки пользователем. Я могу сделать это с:
/*
HttpServletResponse response;
XssfWorkbook excel.write(response.getOutputStream());
*/
@GET
@Path("/excel/")
@Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
public XSSFWorkbook exportReadingsAsExcel(@Context HttpServletResponse webResponse)
{
XSSFWorkbook excel = createExcel();
setHeader(webResponse, "export.xlsx");
try {
excel.write(webResponse.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
return excel; //ERROR IS HERE
}
Но мне также нужна функция для возврата XSSFWorkbook по другим причинам. И я надеялся, что вместо того, чтобы использовать веб-ответ, Джерси мог бы написать его.
Спасибо за помощь.
(Я немного новичок в Джерси и XSSF, поэтому, пожалуйста, потерпите меня, если я не согласен с моей терминологией или пониманием)
2 ответа
Вам нужно написать свой собственный писатель для XSSFWorkbook (или найти его) и подключить его к Джерси, например:
@Provider
@Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
public class CustomXSSFWorkbookWriter implements MessageBodyWriter {
//This methode is the most important for you
@Override
public void writeTo(Object target, Class type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap httpHeaders, OutputStream outputStream)
throws IOException {
Затем вы должны добавить пакет этого класса в свой web.xml
как это:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.packages.to.your.views;com.packages.to.your.providers</param-value>
</init-param>
Джерси будет вашим собственным писателем для производства этого конкретного формата. Извините, я ничего не знаю о XSSFWorkbook.
Надеюсь, решит вашу проблему.
Я смог решить проблему, вернув StreamingOutput через Джерси. Затем я записал байты StreamingOutput в OutputStream. Я получил byte[] из OutputStream, записал этот OutputStream в InputStream, а затем создал новую XSSFWorkbook из этого InputStream. Я знаю, что это очень грязный способ сделать это. Я попробую способ, предложенный выше -Camille R, и надеюсь, что это будет более чистое решение. Но тем временем...
@GET
@Path("/excel/")
@Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
public StreamingOutput exportReadingsAsExcel(@Context HttpServletResponse webResponse)
{
XSSFWorkbook excel = createExcel();
setHeader(webResponse, "export.xlsx");
StreamingOutput streamOutput = new StreamingOutput(){
public void write(OutputStream output) throws IOException, WebApplicationException {
try {
excel.write(output);
} catch (Exception e) {
throw new WebApplicationException(e);
}
}
};
return streamOutput;
}
По функции приемника:
private XSSFWorkbook createExcel(StreamingOutput mStream){
XSSFWorkbook excel = new XSSFWorkbook();
try {
ExcelOutputStream out = new ExcelOutputStream();
excel.write(out);
ByteArrayInputStream inputStream = new ByteArrayInputStream(out.getBytes());
excel = new XSSFWorkbook(inputStream ;
} catch (WebApplicationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
class MyOutputStream extends OutputStream {
private ByteArrayOutputStream myByteArray;
public MyOutputStream(){
myByteArray = new ByteArrayOutputStream();
}
@Override
public void write(int b) throws IOException {
// TODO Auto-generated method stub
myByteArray.write(b);
}
public byte[] getBytes(){
return myByteArray.toByteArray();
}
}