I want to export data to an Excel file via HTTP Request. I have a class implementing the request handler interface.
I set the response body to something like header1 \t header2 \t \n content1 \t content2 \t \n
The content-type is application/msexcel; charset=iso-8859-2, and the Content-Dispositionis set to attachment; filename=Excel.xls
This approach works nice for a server-side Javascript application, but when doing the same in ABAP the created Excel File has no columns or rows at all, the whole excel-formatted response body string is inserted in one cell.
Does anyone know, what is the difference between JS and ABAP?
Thanks and best Regards!
I use this sample:
* list1 is an internal table
loop at list1 INTO wa .
CONCATENATE output WA-weekday WA-x WA-DTEXT
WA-SCHKZ WA-BEGTM WA-ENDTM
CL_ABAP_CHAR_UTILITIES=>CR_LF
INTO output SEPARATED BY TAB .
endloop.
* utf-16le , format for excel file
app_type1 = 'APPLICATION/MSEXCEL;charset=utf-16le'.
* convert string to xstring
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = output
mimetype = 'APPLICATION/MSEXCEL;charset=utf-16le'
IMPORTING
buffer = l_xstring.
CONCATENATE cl_abap_char_utilities=>byte_order_mark_little
l_xstring
INTO l_xstring IN BYTE MODE.
CALL METHOD cl_bsp_utility=>download
EXPORTING
object_s = l_xstring
content_type = app_type
content_disposition = 'attachment;filename=webforms.xls'
response = response
navigation = navigation.
You can also see this thread in sdn:
http://scn.sap.com/people/thomas.jung/blog/2004/08/09/bsp-download-to-excel-in-unicode-format
Related
I have to encode some HTML source code into base64 format before form submission, and then decode it back to original code in the code behind. Here is the testing code by MsgBox:
MsgBox(HttpContext.Current.Request.Form("encodedSourceCode"))
MsgBox(Convert.ToString(HttpContext.Current.Request.Form("encodedSourceCode").GetType()))
Dim b = Convert.FromBase64String(HttpContext.Current.Request.Form("encodedSourceCode"))
Dim html = System.Text.Encoding.UTF8.GetString(b)
MsgBox(html)
And I have added an alert() for encodedSourceCode in client script.
The results turn out to be:
First MsgBox: Empty
Second MsgBox: "System.String"
Last MsgBox: Original HTML source code
And the JS alert dialog shows the base64 string, which consists of a bunch of digits and alphabets.
In short, everything is fine, except the first MsgBox, which is supposed to be base64 encoded string but turns out to be empty. Why? Is it normal?
Actually it does not matter much because even the final result (after decoding) seems to have no problem, but I'm just curious why the interim result is not shown as what it's supposed to be.
It seems that the string is simply too long without 'wrappable' characters, I suppose. MsgBox cuts out the 'last word' and shows nothing.
This may confirm it:
dim test = HttpContext.Current.Request.Form("encodedSourceCode")
MsgBox(test) ' empty
test = test.Substring(0, 20)
MsgBox(test) ' shows the first 20 characters
Testing in LinqPad, I get the limit around 43.000 characters:
MsgBox("".PadLeft(43000, "a"))
MsgBox("".PadLeft(44000, "a"))
MsgBox("".PadLeft(43000, "a") & " " & "".PadLeft(1000, "a"))
1st: shows text.
2nd: shows empty box, length = 44.000
3rd: shows text, although the total length is 44.001, but wrappable at the space.
It definitely has nothing to do with base64 strings as they are simple strings. Here the proof:
Dim myString = "Hello world, this is just an ɇxâmpŀƏ ʬith some non-ansi characters..."
Dim myEncoding As Encoding = Encoding.UTF8
MsgBox(myString)
Dim myBase64 = Convert.ToBase64String(myEncoding.GetBytes(myString))
MsgBox(myBase64)
Dim myStringAgain = myEncoding.GetString(Convert.FromBase64String(myBase64))
MsgBox(myStringAgain)
MsgBox(If(StringComparer.Ordinal.Equals(myString, myStringAgain), "same", "different"))
The line
MsgBox(Convert.ToString(HttpContext.Current.Request.Form("encodedSourceCode").GetType()))
results in "System.String" because you convert the name of the type to a string (see xxx.GetType()).
So I am going off memory here because I cannot see the code I am trying to figure this out for at the moment, but I am working with some old VB Script code where there is a data connection that is set like this:
set objCommand = Server.CreateObject("ADODB.command")
and I have a field from the database that is being stored in a variable like this:
Items = RsData(“Item”).
This specific field in the database is a long string of
text:
(i.e. “This is part of a string of text…Header One: Here is text after header one… Header Two: Here is more text after header two”).
There are certain parts of the text that I wish to store as a variable that are between two index positions in the long string of text within that field. They are separated by headers that are stored in the text field above like this: “Header One:” and “Header Two:”, and I want to capture all text that occurs in between those two headers of text and store them into their own variable (i.e. “Here is text after header one…”).
How do I achieve this? I have tried to use the InStr method to set the index but from how I understand how this works it will only count the beginning of where a specific part of the string occurs. Am I wrong in my thinking of this? Since that is the case, I am also having trouble getting the Mid function to work. Can some one please show me an example of how this is supposed to work? Remember, I am only going off of memory so please forgive me that I am unable to provide better code examples now. I hope my question makes sense!
I am hopeful that someone can help me with an answer tonight so I can try this out tomorrow when I am near the code again! Thank you for your efforts and any help offered!
You can extract all the substrings starting with the text Header and ending just before either the next Header or end-of-string. I have used regular expression to implement that and it is working for me. Have a look at the code below. If I get a simpler(non-regex solution), I will update the answer.
Code:
strTest = "Header One: Some random text Header Two: Some more text Header One: Some random textwerwerwefvxcf234234 Header Three: Some more t2345fsdfext Header Four: Some randsdfsdf3w42343om text Header Five: Some more text 123213"
set objReg = new Regexp
objReg.Global = true
objReg.IgnoreCase = false
objReg.pattern = "Header[^:]+:([\s\S]*?)(?=Header|$)" '<---Regex Pattern. Explained later.
set objMatches = objReg.Execute(strTest)
Dim arrHeaderValues() '<-----This array contains all the required values
i=-1
for each objMatch in objMatches
i = i+1
Redim Preserve arrHeaderValues(i)
arrHeaderValues(i) = objMatch.subMatches.item(0) '<---item(0) indicates the 1st group of each match
next
'Displaying the array values
for i=0 to ubound(arrHeaderValues)
msgbox arrHeaderValues(i)
next
set objReg = Nothing
Regex Explanation:
Header - matches Header literally
[^:]+: - matches 1+ occurrences of any character that is not a :. This is then followed by matching a :. So far, keeping the above 2 points in mind, we have matched strings like Header One:, Header Two:, Header blabla123: etc. Now, whatever comes after this match is relevant to us. So we will capture that inside a Group as shown in the next breakup.
([\s\S]*?)(?=Header|$) - matches and captures everything(including newlines) until either the next Header or the end-of-the-string(represented by $)
([\s\S]*?) - matches 0+ occurrences of any character and capture the whole match in Group 1
(?=Header|$) - match and capture the above thing until another instance of the string Header or end of the string
Click for Regex Demo
Alternative Solution(non-regex):
strTest = "Header One: Some random text Header Two: Some more text Header One: Some random textwerwerwefvxcf234234 Header Three: Some more t2345fsdfext Header Four: Some randsdfsdf3w42343om text Header Five: Some more text 123213"
arrTemp = split(strTest,"Header") 'Split using the text Header
j=-1
Dim arrHeaderValues()
for i=0 to ubound(arrTemp)
strTemp = arrTemp(i)
intTemp = instr(1,strTemp,":") 'Find the position of : in each array value
if(intTemp>0) then
j = j+1
Redim preserve arrHeaderValues(j)
arrHeaderValues(j) = mid(strTemp,intTemp+1) 'Store the desired value in array
end if
next
'Displaying the array values
for i=0 to ubound(arrHeaderValues)
msgbox arrHeaderValues(i)
next
If you don't want to store the values in an array, you can use Execute statement to create variables with different names during run-time and store the values in them. See this and this for reference.
I have XML files I want to put into data sets to export to a database using VB.Net. There is a possibility that new XML files added to this list daily will have special characters (idk why anyone would include "&" in an address entry anyway). After creating the XMLReader, what is the easiest way to replace the escape characters? What would the pseudo code look like? Stream Reader maybe? Or does that work with XMLReader?
Here is my code right now that attempts the data set creation:
For Each file1 In Directory.GetFiles(My.Settings.Local_Meter_Path, "*BadMeter*.xml")
Dim filecreatedate As String = IO.File.GetLastWriteTime(file1)
FN = Path.GetFileName(file1).ToString()
xmlFile = XmlReader.Create(Path.Combine(My.Settings.Local_Meter_Path, FN), New XmlReaderSettings())
ds.ReadXml(xmlFile)
and the spot where I'm getting ampersand entity-name parsing error
<Cell ss:StyleID="Default"><Data ss:Type="String">1440 COUNTY ROAD 40 X-MAS LIGHT & RV #2 CAMP HILL</Data></Cell>
I am trying to upload a CSV file that has special characters using ServletFileUpload of apache common. But the special characters present in the CSV are being stored as junk characters in the database. The special characters I have are Trademark, registered etc. Following is the code snippet.
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
System.out.println("Form field " + name + " with value "
+ Streams.asString(stream, "UTF-8") + " detected.");
}
}
I have tried reading it using BufferendReader, used request.setCharacterEncoding("UTF-8"), tried upload.setHeaderEncoding("UTF-8") and also checked with IOUtils.copy() method, but none of them worked.
Please advice how to get rid of this issue and where it needs to be addressed? Is there anything I need to do beyond servlet code?
Thanks
What database are using? What character set is database using? Characters can be malformed in the database rather than in Java code.
The URL link below will open a new Google mail window. The problem I have is that Google replaces all the plus (+) signs in the email body with blank space. It looks like it only happens with the + sign. How can I remedy this? (I am working on a ASP.NET web page.)
https://mail.google.com/mail?view=cm&tf=0&to=someemail#somedomain.com&su=some subject&body=Hi there+Hello there
(In the body email, "Hi there+Hello there" will show up as "Hi there Hello there")
The + character has a special meaning in [the query segment of] a URL => it means whitespace: . If you want to use the literal + sign there, you need to URL encode it to %2b:
body=Hi+there%2bHello+there
Here's an example of how you could properly generate URLs in .NET:
var uriBuilder = new UriBuilder("https://mail.google.com/mail");
var values = HttpUtility.ParseQueryString(string.Empty);
values["view"] = "cm";
values["tf"] = "0";
values["to"] = "someemail#somedomain.com";
values["su"] = "some subject";
values["body"] = "Hi there+Hello there";
uriBuilder.Query = values.ToString();
Console.WriteLine(uriBuilder.ToString());
The result:
https://mail.google.com:443/mail?view=cm&tf=0&to=someemail%40somedomain.com&su=some+subject&body=Hi+there%2bHello+there
If you want a plus + symbol in the body you have to encode it as 2B.
For example:
Try this
In order to encode a + value using JavaScript, you can use the encodeURIComponent function.
Example:
var url = "+11";
var encoded_url = encodeURIComponent(url);
console.log(encoded_url)
It's safer to always percent-encode all characters except those defined as "unreserved" in RFC-3986.
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
So, percent-encode the plus character and other special characters.
The problem that you are having with pluses is because, according to RFC-1866 (HTML 2.0 specification), paragraph 8.2.1. subparagraph 1., "The form field names and values are escaped: space characters are replaced by `+', and then reserved characters are escaped"). This way of encoding form data is also given in later HTML specifications, look for relevant paragraphs about application/x-www-form-urlencoded.
Just to add this to the list:
Uri.EscapeUriString("Hi there+Hello there") // Hi%20there+Hello%20there
Uri.EscapeDataString("Hi there+Hello there") // Hi%20there%2BHello%20there
See https://stackoverflow.com/a/34189188/98491
Usually you want to use EscapeDataString which does it right.
Generally if you use .NET API's - new Uri("someproto:with+plus").LocalPath or AbsolutePath will keep plus character in URL. (Same "someproto:with+plus" string)
but Uri.EscapeDataString("with+plus") will escape plus character and will produce "with%2Bplus".
Just to be consistent I would recommend to always escape plus character to "%2B" and use it everywhere - then no need to guess who thinks and what about your plus character.
I'm not sure why from escaped character '+' decoding would produce space character ' ' - but apparently it's the issue with some of components.