44import com .genexus .internet .HttpContext ;
55import com .genexus .reports .*;
66import com .genexus .webpanels .GXWebProcedure ;
7+ import org .apache .logging .log4j .Logger ;
8+
9+ import java .io .UnsupportedEncodingException ;
10+ import java .net .URLEncoder ;
11+ import java .nio .charset .StandardCharsets ;
712
813public abstract class GXWebReport extends GXWebProcedure
914{
@@ -99,11 +104,14 @@ protected boolean initTextPrinter(String output, int gxXPage, int gxYPage, Strin
99104 return ret ;
100105 }
101106
102- protected boolean initPrinter (String output , int gxXPage , int gxYPage , String iniFile , String form , String printer , int mode , int orientation , int pageSize , int pageLength , int pageWidth , int scale , int copies , int defSrc , int quality , int color , int duplex )
103- {
104- int x [] = {gxXPage };
105- int y [] = {gxYPage };
106- setResponseOuputFileName ();
107+ protected boolean initPrinter (String output , int gxXPage , int gxYPage , String iniFile , String form , String printer , int mode , int orientation , int pageSize , int pageLength , int pageWidth , int scale , int copies , int defSrc , int quality , int color , int duplex ) {
108+ int x [] = {
109+ gxXPage
110+ };
111+ int y [] = {
112+ gxYPage
113+ };
114+ setResponseOutputFileName ();
107115
108116 getPrinter ().GxRVSetLanguage (localUtil ._language );
109117 boolean ret = getPrinter ().GxPrintInit (output , x , y , iniFile , form , printer , mode , orientation , pageSize , pageLength , pageWidth , scale , copies , defSrc , quality , color , duplex );
@@ -114,10 +122,44 @@ protected boolean initPrinter(String output, int gxXPage, int gxYPage, String in
114122 return ret ;
115123 }
116124
117- private void setResponseOuputFileName (){
118- String outputFileName = filename !=null ? filename : getClass ().getSimpleName ();
119- String outputFileType = filetype !=null ? "." + filetype .toLowerCase (): ".pdf" ;
120- httpContext .getResponse ().addHeader ("content-disposition" , "inline; filename=" + outputFileName + outputFileType );
125+ private void setResponseOutputFileName () {
126+ String outputFileName = (filename != null ? filename : getClass ().getSimpleName ());
127+ String outputFileType = (filetype != null ? "." + filetype .toLowerCase () : ".pdf" );
128+
129+ try {
130+ String encodedFileName = URLEncoder .encode (outputFileName , "UTF-8" ).replace ("+" , "%20" );
131+ boolean isAscii = StandardCharsets .US_ASCII .newEncoder ().canEncode (outputFileName );
132+ String fallbackFileName = outputFileName ;
133+ if (!isAscii ) {
134+ fallbackFileName = outputFileName .replaceAll ("[^\\ p{ASCII}]" , "" );
135+ if (fallbackFileName .isEmpty ()) {
136+ fallbackFileName = "download" ;
137+ }
138+ }
139+ String contentDispositionValue =
140+ "inline; filename=\" " + fallbackFileName + outputFileType + "\" ; " +
141+ "filename*=UTF-8''" + encodedFileName + outputFileType ;
142+
143+ httpContext .getResponse ().addHeader ("Content-Disposition" , contentDispositionValue );
144+ } catch (UnsupportedEncodingException e ) {
145+ httpContext .getResponse ().addHeader ("Content-Disposition" , "inline; filename=\" download" + outputFileType + "\" " );
146+ }
147+ }
148+
149+ /**
150+ * Returns an ASCII version of the filename.
151+ * Non-ASCII characters are replaced with underscore to ensure ASCII compliance.
152+ */
153+ private String asciiFileName (String fileName ) {
154+ StringBuilder asciiFileName = new StringBuilder ();
155+ for (char character : fileName .toCharArray ()) {
156+ if ((character <= 127 )) {
157+ asciiFileName .append (character );
158+ } else {
159+ asciiFileName .append ("_" );
160+ }
161+ }
162+ return asciiFileName .toString ();
121163 }
122164
123165 protected void endPrinter ()
0 commit comments