- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 Spring 的内容协商和 OpenCSV 将 CSV 文件输出到客户端。
所以我有这个 Controller :
@RequestMapping(value = { "", "/" }, method = RequestMethod.GET, produces = "text/csv")
@esponseStatus(HttpStatus.OK)
public Model getCustomersView(HttpServletRequest request, Model model)
throws InvalidBusinessContractDataException {
Customer[] customers = customerService.findCustomers();
return model.addAttribute("customers", customers);
}
这个媒体类型转换器:
@Component("viewNameTranslator")
public final class MediaTypeRequestToViewTranslator implements
RequestToViewNameTranslator {
@Autowired
private ContentNegotiationManager contentNegotiationManager;
private DefaultRequestToViewNameTranslator defaultTranslator = new DefaultRequestToViewNameTranslator();
// a list of media types to ignore - not output on the translated view
private List<String> ignoredTypes = Arrays.asList("text/html");
@Override
public String getViewName(HttpServletRequest request) {
// first resolve the media type (see below)
String mediaType = resolveMediaType(request);
// delegate to the default translator to get the view name
String viewName = defaultTranslator.getViewName(request);
// concatenate the resolved media type to the default name and return it
return viewName + mediaType;
}
private String resolveMediaType(HttpServletRequest request) {
try {
// use the content negotiation manager to resolve the media type
// from the request. The manager does it
// according to its own search path and preferences - using the
// suffix, using the Accept header and
// preferring one of them. The result would always be a single type
// or none at all, but it returns a list
List<MediaType> types = contentNegotiationManager
.resolveMediaTypes(new ServletWebRequest(request));
// resolve to a single type
String type = types == null || types.size() == 0 ? "" : types
.get(0).toString();
// if it's not in the ignored media types - prepend a semi-colon and
// return it
return ignoredTypes.contains(type) ? "" : ";" + type;
} catch (HttpMediaTypeNotAcceptableException e) {
return "";
}
}
}
这个 View :
@Component("customers;text/csv")
public final class CustomerCsvView implements View {
@Override
public String getContentType() {
return "text/csv";
}
@Override
public void render(Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.setContentType("text/csv");
Customer[] customers = (Customer[]) model.get("customers");
CSVWriter writer = new CSVWriter(new OutputStreamWriter(response
.getOutputStream()));
writer.writeNext(new String[] {"id", "fName", "lName"});
for (Customer c : customers) {
System.out.println("FOO");
writer.writeNext(new String[] {
new Long(c.getCustomerId()).toString(), c.getFirstName(), c.getLastName() });
}
}
}
当我用浏览器点击这个 Controller 时,“FOO”在我的控制台中出现两次,弹出一个文件保存对话框,其中包含要下载的 test/csv 文件,并且它是 0 字节。
就像对响应的更改没有保留一样。
怎么了?
最佳答案
在发送数据之前设置内容类型并刷新数据,然后关闭outputwriter
response.setContentType("text/csv;charset=utf-8")
response.setHeader("Content-Disposition","attachment; filename=\yourData.csv\"");
OutputStream resOs= response.getOutputStream();
OutputStream buffOs= new BufferedOutputStream(resOs);
OutputStreamWriter outputwriter = new OutputStreamWriter(buffOs);
CsvWriter writer = new CsvWriter(outputwriter);
// write data in csvwrite in loop
最后关闭flush就关闭了。
outputwriter.flush();
outputwriter.close();
<小时/>
如果使用 @ResponseBody 会更好HttpMessageConverter与 Spring 3.0
在你的 Controller 中你这样做
@RequestMapping(value = "/getFullData2.html", method = RequestMethod.GET, consumes = "text/csv")
@ResponseBody // indicate to use a compatible HttpMessageConverter
public CsvResponse getFullData(HttpSession session) throws IOException {
List<CompositeRequirement> allRecords = compReqServ.getFullDataSet((String) session.getAttribute("currentProject"));
return new CsvResponse(allRecords, "yourData.csv");
}
编写 HttpMessageConverter:
public class CsvMessageConverter extends AbstractHttpMessageConverter<CsvResponse> {
public static final MediaType MEDIA_TYPE = new MediaType("text", "csv", Charset.forName("utf-8"));
public CsvMessageConverter() {
super(MEDIA_TYPE);
}
protected boolean supports(Class<?> clazz) {
return CsvResponse.class.equals(clazz);
}
protected void writeInternal(CsvResponse response, HttpOutputMessage output) throws IOException, HttpMessageNotWritableException {
output.getHeaders().setContentType(MEDIA_TYPE);
output.getHeaders().set("Content-Disposition", "attachment; filename=\"" + response.getFilename() + "\"");
OutputStream out = output.getBody();
CsvWriter writer = new CsvWriter(new OutputStreamWriter(out), '\u0009');
List<CompositeRequirement> allRecords = response.getRecords();
for (int i = 1; i < allRecords.size(); i++) {
CompositeRequirement aReq = allRecords.get(i);
writer.write(aReq.toString());
}
writer.close();
}
}
要绑定(bind)的简单对象
public class CsvResponse {
private final String filename;
private final List<CompositeRequirement> records;
public CsvResponse(List<CompositeRequirement> records, String filename) {
this.records = records;
this.filename = filename;
}
public String getFilename() {
return filename;
}
public List<CompositeRequirement> getRecords() {
return records;
}
}
关于java - Spring内容协商/OpenCSV : Getting a blank CSV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23374518/
我使用了 opencsv 的“http://opencsv.sourceforge.net/#maven-integration ” maven 依赖项,如下所示: net.sf.openc
我正在尝试使用 HeaderColumnNameMappingStrategy 使用 opencsv 读取 csv 文件。 Opencsv 每次都将我的第一列 csv 填充为 null。 这是我的代码
使用 OpenCSV 库,调用 StatefulBeanToCsv.write()我的空值被包裹在引号中。 例子: String[] columns = new String[] { "Col
我正在使用 AndroidStudio,我的应用程序必须读取如下所示的 CSV 文件: "Anmeldung";"1576017126809898";"1547126680978123";"";"";
在我的主课 public static void main(String[] args) { CSVWriter writer = new CSVWriter(new Fi
我使用openCSV导入文件,但通常它只读取文件的一部分。它处理包含约 5k 行的文件,但通常 20k 对他来说是个问题(即使是 1 列的 CSV)。 当我尝试使用 BufferedReader 而不
我试图使用 openCSV java 库在 csv 文件中写入一些公式数据,但它只写入每个单元格中大约 90% 的字符串。是否有任何已知问题可能导致此行为? public static void ma
我正在使用 opencsv 2.3,它似乎没有像我预期的那样处理转义字符。我需要能够处理不使用引号字符的 CSV 文件中的转义分隔符。 示例测试代码: CSVReader reader = new C
我试图从分号分隔的文件中的倒数第二行和第三列获取值。我无法坐下来获取倒数第二行和第三列的值。 我一直在寻找一种方法来实现这一目标,但没有结果。如果有人能用一个例子为我指明正确的方向,我将不胜感激。 这
我正在尝试使用 opencsv 解析 csv 文件。文件中的最后一列有一个参数,实际上是 json。该 json 包含在“”中。问题是 opencsv 正在从 json 中删除一些 "导致我的代码中断
我使用 open csv 来读取只有 2 列的 CSV,例如: "valueA1","valueB of A1" ,"valueB of A1" ,"valueB of A1" ,"valueB of
我陷入了必须读取两个不同的 csv 文件并将它们存储在单个表中的情况。 CSV 文件1: salary,date,user 121,2016-08-01,admin 121,2016-08-01,ad
我有一个 CSV 文件,其中引号内有定界符或未闭合的引号,如何让 CSVReader 忽略引号内的引号和定界符。例如: 123|Bhajji|Maga|39|"I said Hey|" I am "5
我使用的是 opencsv 3.0 版本。由于某种原因,它没有将记录写出到 CSV 文件中。它适用于 2.3 版。但是,我想使用 CSVIterator 类。感谢您的帮助。 public void
我正在尝试使用 opencsv 解析一些公共(public)数据(3.10 版)。下面是获取 CSV 并将记录映射到 POJO 列表的代码片段: URL permitsURL = new URL("h
好的,我有一个 csv 文件: Summary heading1,heading2,heading3 value1,value2,value2 value1,value2,va
我需要有关在 Java 中解析 CSV 数据时遇到的问题的建议。 我有一个 CSV 文件,其中包含以下格式的数据 name, gender, address_first_line, address_s
我编写了一个脚本,使用 tokenize 在 groovy 中解析 .csv 文件,但最终没有完全满足我的需要,我正在尝试使用 openCSV 库,但我不确定如何解析各个列。这是到目前为止我的代码:
我正在使用 openCSV 的 CsvToBean 类。该 bean 具有日期字段。 @CsvDate(value = "yyyy-MM-dd") @CsvBindByPosition(positio
我有以下 CSV 文件, "id","Description","vale" 1,New"Account","val1" 我无法使用 OpenCSV 读取上述 CSV 文件。它无法读取 New"Acc
我是一名优秀的程序员,十分优秀!