我有一个小型的Spring 4应用程序,它从表单接收数据,将其保存在MariaDB中,将其显示在网页上,如果被要求返回使用Apache POI写入xls(MS Excel)文档的数据。 该应用程序适用于英文文本。
以下是我运行以创建和填充db表的命令:
CREATE DATABASE testdb COLLATE 'utf16_general_ci';
use testdb;
create table testtable( id INTEGER PRIMARY KEY AUTO_INCREMENT, text1 VARCHAR(100), text2 VARCHAR(100), text3 VARCHAR(200));
INSERT INTO testtable (text1,text2,text3) VALUES ('אבג','דהו','זחט');
这是用于显示和发出请求的JSP页面:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-16">
</head>
<body>
<table border=1>
<tr><th>TEXT1</th><th>TEXT2</th><th>TEXT3</th></tr>
<c:forEach items="${rowList}" var="row">
<tr>
<td>${row.getText1()}</td>
<td>${row.getText2()}</td>
<td>${row.getText3()}</td>
</tr>
</c:forEach>
<tr><td><br><form method="GET" action="/clear"><input type="submit" value="CLEAR TABLE" /></form></td>
<td><br><form method="GET" action="/getxls"><input type="submit" value="download XLS file" /></form></td>
<td></td>
</tr>
</table>
<br>
<table border=1>
<tr><td>
<form method="POST" action="/add" accept-charset="UTF-16" >
<label>TEXT1</label>
<input type="text" name="text1" /><br>
<label>TEXT2</label>
<input type="text" " name="text2" /><br>
<label>TEXT3</label>
<input type="text" name="text3" />
<br>
<input type="submit" />
</td></tr>
</table>
</form>
</body>
</html>
这是应用程序的单个控制器:
@Controller
public class HomeController {
@Autowired
UserDao userDao;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index(ModelMap model){
model.addAttribute("rowList", userDao.getUserList());
return "home";
}
@RequestMapping(value = "/clear", method = RequestMethod.GET)
public String clearTable(){
userDao.deleteAllUsers();
return "home";
}
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addCoding(
@RequestParam("text1") String t1,
@RequestParam("text2") String t2,
@RequestParam("text3") String t3,
ModelMap model
) throws Exception{
User b = new User(java.net.URLDecoder.decode(t1,"UTF-16"), t2, t3);
userDao.addUser(b);
model.addAttribute("rowList", userDao.getUserList());
return "home";
}
@RequestMapping(value = "/getxls", method = RequestMethod.GET )
public void export1( HttpServletResponse response ) throws IOException {
List<User> users = userDao.getUserList();
Workbook wb = new HSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");
// creating headers for data columns
Row row = sheet.createRow(0);
row.createCell(0).setCellValue("TEXT1");
row.createCell(1).setCellValue("TEXT2");
row.createCell(2).setCellValue("TEXT3");
int rowIndex = 1;
for(User user : users){
row = sheet.createRow(rowIndex);
row.createCell(0).setCellValue(createHelper.createRichTextString(user.getText1()));
row.createCell(1).setCellValue(createHelper.createRichTextString(user.getText2()));
row.createCell(2).setCellValue(user.getText3());
rowIndex++;
}
response.setHeader("Content-Disposition","attachment; filename=data.xls");
ServletOutputStream out = response.getOutputStream();
wb.write(out);
out.flush();
out.close();
}
}
控制器中的数据对象称为User
,但对于db id和三个int
来说它实际上只是String
使用与提交它的MariaDB控制台相同的希伯来语输入填写表单会产生以下结果:
在所有三个结果显示中,第1行和第3行的内容相同。 (或者至少是输入) 使用MariaDB控制台输入第1行。 第3行输入了网页。 如何处理Web请求,以便在xls文件中第1行和第3行是相同的? 另外,如何在网页上正确显示第1行的数据?
答案 0 :(得分:0)
更正JPS页面: 1)添加
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="ISO-8859-1"%>
到文档的顶部,这将正确显示从数据库中提取的有效数据。
2)在<form>
rag中,将属性accept-charset
的值从UTF-16
更改为ISO-8859-1
。这将以&#xxxx;
的形式返回阿拉伯语和希伯来语字符,其中每个x
都是十进制数字。
校正逻辑 - 将所述&#xxxx;
个字符转换为正确的阿拉伯语/希伯来语字符:
希伯来语'Aleph'='א'传递为א
。
在java String.valueOf(Character.toChars(Integer.parseInt("1488", 10)));
中将返回正确的'א'字符;所以我添加了以下函数来在控制器中输入第一个东西:
public static String y(String txt){
String formatedString = "";
char[] charArr = txt.toCharArray();
for (int i=0; i<charArr.length; i++){
if(charArr[i] != '&')
formatedString += charArr[i];
else {
if (i+5 <= charArr.length && charArr[i+1] == '#'){
String temp = "";
for (int j=i+2;j<=i+5;j++)
temp += charArr[j];
if (temp.matches("-?\\d+(\\.\\d+)?")){
formatedString += String.valueOf(Character.toChars(Integer.parseInt(temp, 10)));
i=i+6;
}
} else
formatedString += charArr[i];
}
}
return formatedString;
}
答案 1 :(得分:0)
不使用utf-16。使用UTF-8,在MySQL内部称为utf8或utf8mb4。
在
在连接时,您必须指定客户端使用的编码。
表中的列必须声明为CHARACTER SET utf8
(或utf8mb4)。
(阿拉伯语和希伯来语都得到处理。)
如果您确实在客户端使用UTF-16编码,则可以使用utf16进行连接。但我建议在表格中使用utf8或utf8mb4。 MySQL将动态转换。