好的,我很困惑。我的问题是我想将我的Excel电子表格的内容发送到UTF8编码的HTTP POST Web服务 - 即我想支持阿拉伯语文本。
我可以遍历写入流的电子表格的单元格:
Dim fsT 'As New Stream
Set fsT = CreateObject("ADODB.Stream")
fsT.Type = 2'Specify stream type - we want To save text/string data.
fsT.Charset = "utf-8" 'Specify charset For the source text data.
fsT.Open 'Open the stream And write binary data To the object
如果我希望将其保存到文件中,我可以保留我的阿拉伯文字。
当我发送给我的服务时,我将其作为二进制文件发送,这可能是我的垮台。
'Change stream type To binary
fsT.Position = 0
fsT.Type = adTypeBinary
其次是
Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")
Call oHttp.Open("POST", pHtml, False)
oHttp.setRequestHeader "Content-Type", "application/text"
oHttp.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
Call oHttp.send(fsT.Read)
但是我也尝试以文本形式发送,而不更改流类型
Call oHttp.send(fsT.ReadText)
在这两种情况下,我服务器上收到的阿拉伯文字只是一系列问号??? ??? ???如果我查看sft.ReadText的输出,那么顺便说一句,这是我在VBA上得到的。
所以 - 我可以输出一个文件,但不能丢失我的文本。
我的VBA不是很好,而且我确定我将被告知我有多愚蠢,但冒着风险,任何人都可以提供帮助 - 我一直在尝试许多排列的东西,我只是可以没有收到发送的文字。
答案 0 :(得分:1)
如果两个站点(服务器和客户端)都使用相同的语言(在本例中为HTTP)并且服务器确实希望POST请求主体中只有UTF-8编码的字节,那么它应该可以工作。
当然这是一个断言。但我会证明这一点。
所以我运行了以下简单的Java服务器:
import java.net.*;
import java.io.*;
class SimplestServerPOST extends Thread {
private ServerSocket srvSock = null;
private Socket sock = null;
private BufferedInputStream bin = null;
private DataOutputStream out = null;
private int contentLength = 0;
private int c = 0;
SimplestServerPOST(int port, int timeout) {
super();
try {
System.out.println("Server start.");
srvSock = new ServerSocket(port, 5);
srvSock.setSoTimeout(timeout);
start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
System.out.println("Server run.");
while (true) {
try {
sock = srvSock.accept();
//Begin request-handling
try {
StringBuffer headerLine = new StringBuffer("");
bin = new BufferedInputStream(sock.getInputStream());
out = new DataOutputStream(sock.getOutputStream());
while ((c = bin.read()) >= 0) {
if ((c == 10) || (c == 13)) { //if there is a linebreak, then the line ends
if (c == 13) { //handle CRLF linebreak
bin.mark(1);
if (bin.read() != 10) bin.reset();
}
if (headerLine.length() == 0) break; //the whole header section ends if the first empty line occurs
//get the content-length header
if (headerLine.toString().toLowerCase().startsWith("content-length")) {
contentLength = Integer.parseInt(headerLine.toString().split(" ")[1]);
}
System.out.println(headerLine.toString());
headerLine.delete(0, headerLine.length()); //new headerline
} else {
headerLine.append((char)c); //get one byte for headerline
}
}
byte[] buffer = new byte[contentLength];
bin.read(buffer);
System.out.println(new String(buffer, "UTF-8"));
FileWriter fw = new FileWriter("POSTContent.txt");
fw.write(new String(buffer, "UTF-8"));
fw.close();
out.writeBytes("HTTP/1.1 200 OK\r\n");
out.writeBytes("Connection: close\r\n");
out.writeBytes("\r\n");
out.close();
} catch(Exception e) {
e.printStackTrace();
}
//End request-handling
sock.close();
} catch (InterruptedIOException e) {
try {
int sSTo = srvSock.getSoTimeout();
// This is only to understand the functionality.
//System.out.println("No requests for " + sSTo + "ms.");
} catch (Exception et) {
et.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void finalize() {
if (srvSock != null) {
try {
srvSock.close();
} catch (Exception e) {
e.printStackTrace();
}
srvSock = null;
}
}
}
class SimplestServerPOSTMain {
public static void main(String[] args) {
SimplestServerPOST srv = new SimplestServerPOST(2000, 1000);
}
}
我从以下VBA向此服务器发送POST请求:
Sub test()
Set oADOStream = CreateObject("ADODB.Stream")
oADOStream.Type = 2
oADOStream.Charset = "utf-8"
oADOStream.Open
oADOStream.WriteText "Test umlauts: äöü", 1
oADOStream.WriteText "Test euro sign: €", 1
oADOStream.WriteText "Test arabic: " & ChrW(1587) & " " & ChrW(1588) & " " & ChrW(1589) & " " & ChrW(1590), 1
oADOStream.Position = 0
Set oWinHTTP = CreateObject("MSXML2.XMLHTTP.6.0")
oWinHTTP.Open "POST", "http://192.168.0.10:2000", False
'oWinHTTP.Send oADOStream.ReadText
oADOStream.Type = 1
oWinHTTP.Send oADOStream.Read
End Sub
结果是:
此控制台是Linux控制台。 Windows控制台可能无法正确显示字符。但文件POSTContent.txt应正确包含它们。
答案 1 :(得分:1)
好的 - 谢谢你的帮助。我不知道为什么,但没有一个建议奏效。然而,我找到了一个适合我的解决方案。它是:
我所做的一个例子如下:
Dim fsT 'As New Stream
Set fsT = CreateObject("ADODB.Stream")
fsT.Type = adTypeBinary 'Specify stream type - we want To save text/string data.
Dim b() As Byte
For Each cell In ActiveSheet.UsedRange.Cells
b = cell.Value
fsT.Write b
Next
fsT.Position = 0
Call oHttp.Open("POST", pHtml, False)
oHttp.setRequestHeader "Content-Type", "application/text;charset=UTF-8"
Call oHttp.send("" & fsT.Read)
注意最后一行,如果我删除字符串的串联,它不会以阿拉伯语的形式来到服务器。
我想也许这个问题的另一个答案不起作用的原因是我获取文本(cell.Value)而不是直接将UniCode写入流中的方式。
答案 2 :(得分:1)
从你的答案我怀疑。
您正在做的是以下内容:
您在二进制ADODB.Stream
中编写纯未编码的Unicode字节。然后使用连接"" & fsT.Read
创建Unicode字符串。与在https://msdn.microsoft.com/en-us/library/ms763706%28v=vs.85%29.aspx中提到的一样:"如果输入类型是BSTR,则响应始终编码为UTF-8。"因此IXMLHTTPRequest
会将此字符串编码为UTF-8。
带有ADODB.Stream
的文字.Charset = "utf-8"
中还会包含一个Unicode字符串.ReadText
。但在更改为二进制文件后,它将在其.Read
的开头有一个UTF-8 BOM(EFBBBF)。这个BOM令您的网络服务感到困惑。
请尝试
Set fsT = CreateObject("ADODB.Stream")
fsT.Charset = "UTF-8"
fsT.Type = 2
fsT.Open
For Each cell In ActiveSheet.UsedRange.Cells
fsT.WriteText cell.Value
Next
fsT.Position = 0
Set oHttp = CreateObject("MSXML2.XMLHTTP.6.0")
oHttp.Open "POST", pHtml, False
oHttp.send "" & fsT.ReadText
也会奏效。如果是这样,那么在我看来这是更清洁的解决方案。