tomcat JSP生成Excel电子表格(XLS)下载

rm5edbpk  于 2022-11-13  发布在  其他
关注(0)|答案(7)|浏览(135)

我有这个应用程序,我在JSP中开发,我希望从数据库中导出一些数据在XLS(MS Excel格式)。
在tomcat下,是否可以像普通的Java应用程序一样编写一个文件,然后生成一个指向该文件的链接?或者,是否需要使用特定的API?
执行此操作时是否会出现权限问题?

polkgigr

polkgigr1#

虽然您可以使用JExcelAPI等成熟的库,但如果您将响应MIME类型设置为“application/vnd.ms-excel”之类的内容,Excel也将读取CSV和纯HTML表。
根据电子表格需要的复杂程度,CSV或HTML可以在没有第三方库的情况下为您完成这项工作。

9vw9lbht

9vw9lbht2#

不要使用内容类型为application/vnd.ms-excel的纯HTML表格。这样做基本上是在用错误的内容类型欺骗Excel,这会导致最新版本的Excel出现错误和/或警告。在Excel中编辑和保存时,它还会破坏原始HTML源文件。请不要这样做。
CSV是一种标准格式,Excel默认支持它,而且它很容易生成,内存效率也很高。虽然有库,但你也可以用不到20行的代码轻松地编写一个CSV(对于那些无法抗拒的人来说很有趣)。你只需要遵守RFC 4180规范,它基本上只包含3条规则:
1.字段以逗号分隔。
1.如果逗号出现在字段中,则必须用双引号将字段括起来。
1.如果双引号出现在字段中,则字段必须用双引号括起来,并且字段中的双引号必须用另一个双引号转义。
下面是一个启动示例:

public static <T> void writeCsv (List<List<T>> csv, char separator, OutputStream output) throws IOException {
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
    for (List<T> row : csv) {
        for (Iterator<T> iter = row.iterator(); iter.hasNext();) {
            String field = String.valueOf(iter.next()).replace("\"", "\"\"");
            if (field.indexOf(separator) > -1 || field.indexOf('"') > -1) {
                field = '"' + field + '"';
            }
            writer.append(field);
            if (iter.hasNext()) {
                writer.append(separator);
            }
        }
        writer.newLine();
    }
    writer.flush();
}

下面是一个如何使用它的示例:

public static void main(String[] args) throws IOException {
    List<List<String>> csv = new ArrayList<List<String>>();
    csv.add(Arrays.asList("field1", "field2", "field3"));
    csv.add(Arrays.asList("field1,", "field2", "fie\"ld3"));
    csv.add(Arrays.asList("\"field1\"", ",field2,", ",\",\",\""));
    writeCsv(csv, ',', System.out);
}

在Servlet中(是的,Servlet,不要使用JSP!),您基本上可以执行以下操作:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String filename = request.getPathInfo().substring(1);
    List<List<Object>> csv = someDAO().findCsvContentFor(filename);
    response.setHeader("content-type", "text/csv");
    response.setHeader("content-disposition", "attachment;filename=\"" + filename + "\"");
    writeCsv(csv, ';', response.getOutputStream());
}

将这个servletMap到类似/csv/*的对象上,然后调用类似http://example.com/context/csv/filename.csv的对象,就这样。
请注意,我添加了单独指定分隔符字符的可能性,因为Excel是否接受逗号,或分号;作为CSV字段分隔符可能取决于所使用的区域设置。请注意,我还将文件名添加到了URL pathinfo中,因为雷德蒙团队开发的某个Web浏览器无法使用正确的文件名保存下载。

yuvru6vn

yuvru6vn3#

你可能需要一个库来操作Excel文件,比如JExcelAPI(“jxl”)或POI。我更熟悉jxl,它当然可以写文件。你可以生成它们,并通过提供URL来存储它们,但我不会。生成的文件是一个痛苦。它们增加了并发性、清理过程等形式的复杂性。
如果您可以动态生成文件并通过标准servlet机制将其流式传输到客户机。
如果生成了很多次,或者生成的代价很高,那么你可以缓存结果,但是我更倾向于把它保存在内存中,而不是作为一个文件。如果可以的话,我当然会避免通过URL直接链接到生成的文件。如果你通过servlet,它将允许你以后改变你的实现。这和OO设计中的封装概念是一样的。

xkftehaa

xkftehaa4#

POI或JExcel都是很好的API。我个人喜欢更好的POI,加上POI是不断更新的。此外,在线有更多的关于POI的资源比JExcel,以防你有任何问题。然而,这两个做得很好。

hgb9j2n6

hgb9j2n65#

也许你应该考虑使用一些报告工具,并选择将文件导出为XLS格式。我的建议是JasperReports

oogrdqng

oogrdqng6#

try {
            String absoluteDiskPath =  test.xls";
            File f = new File(absoluteDiskPath);
            response.setContentType("application/xlsx");
            response.setHeader("Content-Disposition", "attachment; filename=" + absoluteDiskPath);
            String name = f.getName().substring(f.getName().lastIndexOf("/") + 1, f.getName().length());
            InputStream in = new FileInputStream(f);
            out.clear(); //clear outputStream prevent illegalStateException write binary data to outputStream
            ServletOutputStream outs = response.getOutputStream();
            int bit = 256;
            int i = 0;
            try {
                while ((bit) >= 0) {
                    bit = in.read();
                    outs.write(bit);
                }
                outs.flush();
                outs.close();
                in.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } finally {
                try {
                    if(outs != null)
                        outs.close(); 
                    if(in != null)
                        in.close(); 
                }catch (Exception ioe2) {
                    ioe2.printStackTrace(); 
                }
            }
    } catch (Exception ex) {
        ex.printStackTrace();

    }
vsmadaxz

vsmadaxz7#

我试过像下面的JSP,它是工作正常.

<% String filename = "xyz.xls"; 

   response.setContentType("application/octet-stream");

   response.setHeader("Content-Disposition","attachment; filename=\"" + filename + "\"");   

   java.io.File excelFile=new java.io.File("C:\\Users\\hello\\Desktop\\xyz.xls");

   java.io.FileInputStream fileInputStream=new java.io.FileInputStream(excelFile);

   byte[] bytes = new byte[(int) excelFile.length()];

   int offset = 0;

   while (offset < bytes.length)

   {

  int result = fileInputStream.read(bytes, offset, bytes.length - offset);
  if (result == -1) {
      break;
  }
  
  offset += result;
 
  }

  javax.servlet.ServletOutputStream outs = response.getOutputStream();
  outs.write(bytes);
  outs.flush();
  outs.close();
  fileInputStream.close();   
  %>

相关问题