从4.1版起,APEX向终端用户开放了CSV数据的Import功能。
美中不足的是,默认的文字编码为UTF-8,而从EXCEL等软件保存的CSV数据则往往不是UTF-8,这就要求终端用户使用第三方转换软件。
总是在抱怨,这些软件大佬,为什么总是这么的不善解人意?比如说,ORACLE在做APEX时,只要留一个选项,让大家选择文件的编码方式不就行了?
微软也是的,在保存CSV时,让大家选择编码方式就那么难以实现?
抱怨归抱怨,问题还要自己解决。
因为对于IT知识不足的用户,让他们选取第三方软件转变文字编码显得有些苛刻。
所以,最好通过APEX提供一个中间页面,让用户选择CSV文件后,由程序进行转换。
考虑到APEX的用户界面的流程,这种转换不想抛给Oracle服务器。因为在服务器上转换后又要求用户下载,然后再提供给APEX的Import页面。这样比较麻烦。
所以,采用在用户端解决转换问题。可以使用的方法有二。
其一,使用浏览器依存的方法,比如,ActiveX(IE), XPCOM(FF),FILEAPI(Chrome)等。
这个方法可以使用Javascript,写作简单。但是多种浏览器的对应却不是小事。
其二,使用Java Applet。
此法可以不考虑浏览器种类,但是客户端对Applet的Security要求比较严,需要进行Security Policy的配置,或对Applet施加电子署名。
这里介绍第2种方法。
对Java Applet进行电子署名后,只要求首次运行时用户同意执行。对于公司内部系统还是一种可以接受的方法。
1. 文件编码转换的核心部分
这需要通过 OutputStreamWriter 实现。详情可参照以下URL:
http://www.java2s.com/Code/Java/Development-Class/ConvertfileinSJIStoUTF8.htm
java支持的编码方式可参照:
http://docs.oracle.com/javase/1.5.0/docs/guide/intl/encoding.doc.html
2. Applet的GUI部分
需要使用awt和swing库函数。虽然实现的是HTML FORM类似的输入,按钮功能,但做法完全不同。详情可参照以下URL:
http://www.javabeginner.com/java-swing/java-jlabel-class-example
3. 对jar文件署名
3.1 如果没有钥匙,要先制作。比如
keytool -genkey -alias MyKey -validity 365
这里制作的密钥别名为 MyKey 有效期限为 365 天。
此操作可按屏幕提示进行,一次就行。(要记住自己输入的密码)
3.2 署名
jarsigner MyApplet.jar MyKey
这里假设你已经实现生成了名为MyApplet.jar的可执行文件。
会要求你输入密码。
编译到署名的各个步骤:
javac MyApplet.java
jar cvf MyApplet.jar *.class
jarsigner MyApplet.jar MyKey
4. 从javascriipt中读取Java信息
需要从javascriipt中读取Java信息。Java是OOP语言,javascript可以通过Java定义的Method和Java交换信息。详情可参照以下URL:
http://www.rgagnon.com/javadetails/java-0183.html
5. Java 代码 (MyApplet.java)
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import javax.swing.border.*;
// file handle
import java.io.IOException;
// for UTF-8
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class MyApplet extends JApplet implements ActionListener {
private JPanel pane = null;
private JScrollPane scrolling = null;
private JTextPane fileBox = null;
private JTextField tfFilename = null;
private JButton butLoad = null;
private JButton butFile = null;
private final String CNVT = "convert";
private final String OPEN = "open";
public String fileName = "";
public String fileNameOut = "";
public String charSet = "EUC_CN";
public String charSetOut = "UTF8";
public String cnvtStatus = "false";
public void setAll(String newFileName, String newFileNameOut,String newCharSet, String newCharSetOut, String newStatus) {
fileName = newFileName;
fileNameOut = newFileNameOut;
tfFilename.setText(newFileName);
charSet = newCharSet;
charSetOut = newCharSetOut;
cnvtStatus = "false";
}
public String getAll() {
//return fileName+"-->"+fileNameOut+", "+charSet+"-->"+charSetOut;
return fileName+"#"+fileNameOut+"#"+charSet+"#"+charSetOut+"#"+cnvtStatus;
}
public void init() {
try {
jbInit();
} catch(Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
pane = new JPanel();
pane.setBounds(new Rectangle(0, 0, 500, 700));
pane.setLayout(null);
pane.setBorder(BorderFactory.createEtchedBorder(
EtchedBorder.LOWERED));
pane.setBackground(new Color(221, 194, 219));
JLabel lblFilenamein = new JLabel("FileName (In):");
lblFilenamein.setBounds(5, 3, 100, 13);
lblFilenamein.setHorizontalAlignment(SwingConstants.LEFT);
lblFilenamein.setVerticalAlignment(SwingConstants.TOP);
pane.add(lblFilenamein);
tfFilename = new JTextField();
tfFilename.setText("");
tfFilename.setBounds(new Rectangle(16, 23, 206, 29));
pane.add(tfFilename);
butLoad = new JButton();
butLoad.setBounds(new Rectangle(331, 23, 80, 30));
butLoad.setText("Convert");
butLoad.setActionCommand(CNVT);
butLoad.addActionListener(this);
pane.add(butLoad);
JLabel lblNote = new JLabel("for FireFox etc.");
lblNote.setBounds(231, 3, 100, 13);
lblNote.setHorizontalAlignment(SwingConstants.LEFT);
lblNote.setVerticalAlignment(SwingConstants.TOP);
lblNote.setForeground(new Color(200, 150, 200));
pane.add(lblNote);
JButton butFile = new JButton( "参照..." );
butFile.setBounds(new Rectangle(231, 23, 80, 30));
butFile.setActionCommand(OPEN);
butFile.addActionListener(this);
butFile.setBackground(new Color(200, 150, 200));
pane.add(butFile);
setContentPane(pane);
}
public void actionPerformed(ActionEvent e) {
try {
// Convert Button process
if (e.getActionCommand().equals(CNVT)) {
String fin = tfFilename.getText();
String fout = fileNameOut;
FileInputStream fis = new FileInputStream(new File(fin));
BufferedReader in = new BufferedReader(new InputStreamReader(fis, charSet));
FileOutputStream fos = new FileOutputStream(new File(fout));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos, charSetOut));
int len = 1024;
char buf[] = new char[len];
int numRead;
while ((numRead = in.read(buf, 0, len)) != -1)
out.write(buf, 0, numRead);
out.close();
in.close();
fileName = fin;
fileNameOut = fout;
JOptionPane.showMessageDialog(null,"Completed. New file is saved as:"+fout);
cnvtStatus = "true";
}
// Open File Button process
if (e.getActionCommand().equals(OPEN)) {
JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory( new File( "C:\\" ) );
int returnVal = fc.showOpenDialog( this );
String afileName = "C:\\image.jpeg" ;
if ( returnVal == JFileChooser.APPROVE_OPTION ){
File aFile = fc.getSelectedFile();
//afileName = aFile.getName();
afileName = aFile.getAbsolutePath();
cnvtStatus = "false";
fileName = afileName;
fileNameOut = fileName + "." + charSetOut;
tfFilename.setText(afileName);
JOptionPane.showMessageDialog(null,"File is :"+afileName);
}
}
}catch(Exception x){x.printStackTrace();}
}
}
6. HTML Code
<HTML><HEAD></HEAD><BODY>
<SCRIPT>
function getAll() {
stringFromJava = document.myApplet.getAll();
parameter = new Array();
parameter = stringFromJava.split("#");
alert(parameter[0]+"-->"+parameter[1]+"; "+parameter[2]+"-->"+parameter[3]+"; "+parameter[4]);
if (parameter[4]=="true"){document.getElementById("FileNameOut").value = parameter[1];}
/**
document.getElementById("FileName").value = parameter[0];
document.getElementById("FileNameOut").value = parameter[1];
document.getElementById("charSetIn").value = parameter[2];
document.getElementById("charSetOut").value = parameter[3];
**/
}
function setAll(obj) {
if (obj.id == "FileNameOut"){
//alert(obj.id);
}
else{
document.getElementById("FileNameOut").value = document.getElementById("FileName").value +"."+ document.getElementById("charSetOut").value;
}
newIn = document.getElementById("FileName").value;
newOut = document.getElementById("FileNameOut").value;
newIns = document.getElementById("charSetIn").value;
newOuts = document.getElementById("charSetOut").value;
document.myApplet.setAll(newIn, newOut, newIns, newOuts, "false");
}
function cvtCharSet(csetin,csetout) {
//Not work. impossible to execute Java method to deal with local files via JS.
newString = document.getElementById("FileName").value;
newName = document.myApplet.cvtCharSet(newString,csetin,csetout);
alert(newName);
}
</SCRIPT>
<FORM>
<table border="0" bgcolor="#DDC2DB" style="font: bold; font-size: 12px;">
<tr>
<td style="width:115px;">File Name (In):</td>
<td style="width:200px;"><INPUT id="FileName" type="file" value="" onChange = "setAll(this);"></td>
<td style="width:100px;">Char Set(In): </td>
<td style="width:100px;"><select id="charSetIn" onChange = "setAll(this);">
<option value="Big5">Big5</option>
<option value="EUC_CN">EUC-CN</option>
<option value="UTF8" selected>UTF-8</option>
<option value="UTF-16">UTF-16</option>
</select>
</td>
</tr>
<tr>
<td style="width:115px;">File Name (Out):</td>
<td style="width:200px;"><INPUT id="FileNameOut" type="text" value="" onChange = "setAll(this);"></td>
<td style="width:100px;">Char Set(Out): </td>
<td style="width:100px;"><select id="charSetOut" onChange = "setAll(this);">
<option value="Big5">Big5</option>
<option value="EUC_CN">EUC-CN</option>
<option value="UTF8" selected>UTF-8</option>
<option value="UTF-16">UTF-16</option>
</select>
</td>
</tr>
</table>
<INPUT type="button" value="get All Values" onClick = "getAll();">
<!--INPUT type="button" value="set File Name" onClick = "setAll();"-->
<input type="reset" name="reset" value="Reset" />
<br>
</FORM>
<object type="application/x-java-applet" NAME="myApplet" height="70" width="532">
<param name="code" value="MyApplet" />
<param name="archive" value="MyApplet.jar" />
Applet failed to run. No Java plug-in was found.
</object>
</BODY></HTML>