[Project] Code modified: user can edit filename to export

After a lot of searching I found the answer: “No way to change the filename dinamically”.

I have modified the code, but it isn’t working yet. So I need your help, please:

It is ‘dhtmlxgrid_export.js’ file’s entire code :

//Parameter 'Filename' ADDED BY SAULOCO
dhtmlXGridObject.prototype.toPDF=function(filename,q,k,l,a,g,c){
	function r(h){
		for(var i=[],e=1;e<b.hdr.rows.length;e++){
			i[e]=[];
			for(var f=0;f<b._cCount;f++){
				var u=b.hdr.rows[e].childNodes[f];
				i[e][f]||(i[e][f]=[0,0]);
				u&&(i[e][u._cellIndexS]=[u.colSpan,u.rowSpan]);
			}
		}
		//ADDED BY SAULOCO. Add to XML a filename tag with the filename value in it.
		var d="<filename><![CDATA["+filename+"]></filename>";
		//ADDED BY SAULOCO. END
		d+="<rows profile='"+h+"'";
		l&&(d+=" header='"+l+"'");
		a&&(d+=" footer='"+a+"'");
		d+="><head>"+b._serialiseExportConfig(i).replace(/^<head/,"<columns").replace(/head>$/,"columns>");
		for(e=2;e<b.hdr.rows.length;e++){
			for(var c=0,g=b.hdr.rows[e],j="",f=0;f<b._cCount;f++)
				if(b._srClmn&&!b._srClmn[f]||b._hrrar[f]&&(!b._fake||f>=b._fake.hdrLabels.length))
					c++;
				else{
					var k=i[e][f],m=k[0]&&k[0]>1?' colspan="'+k[0]+'" ':"";
					k[1]&&k[1]>1&&(m+=' rowspan="'+k[1]+'" ',c=-1);
					for(var n="",p=0;p<g.cells.length;p++)
						if(g.cells[p]._cellIndexS==f){
							n=g.cells[p].getElementsByTagName("SELECT").length?"":_isIE?g.cells[p].innerText:g.cells[p].textContent;
							n=n.replace(/[ \n\r\t\xA0]+/," ");
							break;
						}
					(!n||n==" ")&&c++;
					j+="<column"+m+"><![CDATA["+n+"]]\></column>";
				}
			c!=b._cCount&&(d+="\n<columns>"+j+"</columns>");
		}
		d+="</head>\n";
		d+=o();
		return d;
	}
	function m(){
		var h=[];
		if(g)
			for(var i=0;i<g.length;i++)
				h.push(w(b.getRowIndex(g[i])));
		else 
			for(i=0;i<b.getRowsNum();i++)
				h.push(w(i));
		return h.join("\n");
	}
	function o(){
		var h=["<foot>"];
		if(!b.ftr)
			return"";
		for(var i=1;i<b.ftr.rows.length;i++){
			h.push("<columns>");
			for(var e=b.ftr.rows[i],f=0;f<b._cCount;f++)
				if(!b._srClmn||b._srClmn[f])
					if(!b._hrrar[f]||b._fake&&!(f>=b._fake.hdrLabels.length)){
						for(var a=0;a<e.cells.length;a++){
							var d="",c="";
							if(e.cells[a]._cellIndexS==f){
								d=_isIE?e.cells[a].innerText:e.cells[a].textContent;
								d=d.replace(/[ \n\r\t\xA0]+/," ");
								e.cells[a].colSpan&&e.cells[a].colSpan!=1&&(c=" colspan='"+e.cells[a].colSpan+"' ");
								e.cells[a].rowSpan&&e.cells[a].rowSpan!=1&&(c=" rowspan='"+e.cells[a].rowSpan+"' ");
								break;
							}
						}
						h.push("<column"+c+"><![CDATA["+d+"]]\></column>");
					}
			h.push("</columns>");
		}
		h.push("</foot>");
		return h.join("\n");
		}
	function h(b,a){
		return(window.getComputedStyle?window.getComputedStyle(b,null)[a]:b.currentStyle?b.currentStyle[a]:null)||"";
	}
	function w(a){
		if(!b.rowsBuffer[a])
			return"";
		var c=b.render_row(a);
		if(c.style.display=="none")
			return"";
		for(var e=b.isTreeGrid()?' level="'+b.getLevel(c.idd)+'"':"",f="<row"+e+">",g=0;g<b._cCount;g++)
			if((!b._srClmn||b._srClmn[g])&&(!b._hrrar[g]||b._fake&&g<b._fake.hdrLabels.length)){
				var d=b.cells(c.idd,g);
				if(x){
					var k=h(d.cell,"color"),
						j=h(d.cell,"backgroundColor"),
						l=h(d.cell,"font-weight")||h(d.cell,"fontWeight"),
						m=h(d.cell,"font-style")||h(d.cell,"fontStyle"),
						o=h(d.cell,"text-align")||h(d.cell,"textAlign"),
						n=h(d.cell,"font-family")||h(d.cell,"fontFamily");
					if(j=="transparent"||j=="rgba(0, 0, 0, 0)")
						j="rgb(255,255,255)";
					f+="<cell bgColor='"+j+"' textColor='"+k+"' bold='"+l+"' italic='"+m+"' align='"+o+"' font='"+n+"'>";
				}else 
					f+="<cell>";
					f+="<![CDATA["+(d.getContent?d.getContent():d.getTitle())+"]]\></cell>";
				}
		return f+"</row>";
	}
	function y(){
		var b="</rows>";
		return b;
	}
	var j={row:this.getSelectedRowId(),col:this.getSelectedCellIndex()};
	if(j.row===null||j.col===-1)
		j=!1;
	else{
		var s=this.cells(j.row,j.col).cell;
		s.parentNode.className=s.parentNode.className.replace(" rowselected","");
		s.className=s.className.replace(" cellselected","");
		j.el=s;
	}
	var k=k||"color",x=k=="full_color",b=this;b._asCDATA=!0;
	this.target=typeof c==="undefined"?' target="_blank"':c;
	eXcell_ch.prototype.getContent=function(){
		return this.getValue();
	};
	eXcell_ra.prototype.getContent=function(){
		return this.getValue();
	};
	var t=document.createElement("div");
	t.style.display="none";
	document.body.appendChild(t);
	var v="form_"+b.uid();
	t.innerHTML='<form id="'+v+'" method="post" action="'+q+'" accept-charset="utf-8"  enctype="application/x-www-form-urlencoded"'+this.target+'><input type="hidden" name="grid_xml" id="grid_xml"/> </form>'; 
	document.getElementById(v).firstChild.value=encodeURIComponent(r(k).replace("\u2013","-")+m()+y());
	document.getElementById(v).submit();
	t.parentNode.removeChild(t);
	b=null;
	j&&(j.el.parentNode.className+=" rowselected",j.el.className+=" cellselected");j=null;
};
dhtmlXGridObject.prototype._serialiseExportConfig=function(q){
	function k(a){
		if(typeof a!=="string")
			return a;
		a=a.replace(/&/g,"&amp;");
		a=a.replace(/"/g,"&quot;");
		a=a.replace(/'/g,"&apos;");
		a=a.replace(/</g,"&lt;");
		return a=a.replace(/>/g,"&gt;");}
	for(var l="<head>",a=0;a<this.hdr.rows[0].cells.length;a++)
		if(!this._srClmn||this._srClmn[a])
			if(!this._hrrar[a]||this._fake&&!(a>=this._fake.hdrLabels.length)){
				var g=this.fldSort[a];
				g=="cus"&&(g=this._customSorts[a].toString(),g=g.replace(/function[\ ]*/,"").replace(/\([^\f]*/,""));
				var c=q[1][a],r=(c[1]&&c[1]>1?' rowspan="'+c[1]+'" ':"")+(c[0]&&c[0]>1?' colspan="'+c[0]+'" ':"");
				l+="<column "+r+" width='"+this.getColWidth(a)+"' align='"+this.cellAlign[a]+"' type='"+this.cellType[a]+"' hidden='"+(this.isColumnHidden&&this.isColumnHidden(a)?"true":"false")+"' sort='"+(g||"na")+"' color='"+(this.columnColor[a]||"")+"'"+(this.columnIds[a]?" id='"+this.columnIds[a]+"'":"")+">";
				l+=this._asCDATA?"<![CDATA["+this.getHeaderCol(a)+"]]\>":this.getHeaderCol(a);var m=this.getCombo(a);
				if(m)
					for(var o=0;o<m.keys.length;o++)
						l+="<option value='"+k(m.keys[o])+"'><![CDATA["+m.values[o]+"]]\></option>";
				l+="</column>";
			}
	return l+="</head>";
};
if(window.eXcell_sub_row_grid)window.eXcell_sub_row_grid.prototype.getContent=function(){return"";};
// Parameter 'filename' ADDED BY SAULOCO
dhtmlXGridObject.prototype.toExcel=function(filename,q,k,l,a,g){
// ADDED BY SAULOCO. END
	if(!document.getElementById("ifr")){
		var c=document.createElement("iframe");
		c.style.display="none";
		c.setAttribute("name","dhx_export_iframe");
		c.setAttribute("src","");
		c.setAttribute("id","dhx_export_iframe");
		document.body.appendChild(c);
	}
	var r=' target="dhx_export_iframe"';
	// Parameter 'filename' ADDED BY SAULOCO
	this.toPDF(filename,q,k,l,a,g,r);
	// ADDED BY SAULOCO. END
};

I just add a ‘filename’ parameter and before the xml be create I add a line like “![CDATA[thisisafilename]]”.

After modifying the WEB-INF/src/ExcelGenerator.java file:

import java.io.IOException;
import java.net.URLDecoder;

import javax.servlet.http.*;

import com.dhtmlx.xml2excel.ExcelWriter;


@SuppressWarnings("serial")
public class ExcelGenerator extends HttpServlet {

	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		String xml = req.getParameter("grid_xml");
		xml = URLDecoder.decode(xml, "UTF-8");
// ADDED BY SAULOCO
		String filename = xml.substring(xml.lastIndexOf("<filename><![CDATA[")+19,xml.lastIndexOf("]></filename>"));
		xml = xml.substring(xml.lastIndexOf("</filename>")+11,xml.length());
// ADDED BY SAULOCO. END
		(new ExcelWriter()).generate(xml, resp, filename);
	}
}

Here I “split” the XML file, extract the value from the filename tag, save into a String object, and into the String xml I save the XML “like original” without the “” tag.
And later modifying WEB-INF/src/com/dhtmlx/xml2excel/ExcelGenerator.java:

package com.dhtmlx.xml2excel;
import java.io.IOException;
import java.net.URLDecoder;
import javax.servlet.http.*;


@SuppressWarnings("serial")
public class ExcelGenerator extends HttpServlet {
	private String mode = "csv";
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		String xml = req.getParameter("grid_xml");
		xml = URLDecoder.decode(xml, "UTF-8");
// ADDED BY SAULOCO
		String filename = xml.substring(xml.lastIndexOf("<filename><![CDATA[")+19,xml.lastIndexOf("]></filename>"));
		xml = xml.substring(xml.lastIndexOf("</filename>")+11,xml.length());
// ADDED BY SAULOCO. END
		(new ExcelWriter()).generate(xml, resp, filename);
	}

}

And finally modifying the WEB-INF/src/com/dhtmlx/xml2excel/ExcelWriter.java:

package com.dhtmlx.xml2excel;
import java.io.File;
import java.io.IOException;

import javax.servlet.http.HttpServletResponse;


import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.write.*;
import jxl.write.Number;
import jxl.write.biff.*;


public class ExcelWriter extends BaseWriter {
	private WritableWorkbook wb;
	private WritableSheet sheet;
	private ExcelColumn[][] cols;
	private int colsNumber = 0;
	private ExcelXmlParser parser;
	
	public int headerOffset = 0;
	public int scale = 6;
	public String pathToImgs = "";//optional, physical path
	public int fontSize = 10;

	String bgColor = "";
	String lineColor = "";
	String headerTextColor = "";
	String scaleOneColor = "";
	String scaleTwoColor = "";
	String gridTextColor = "";
	String watermarkTextColor = "";

	private int cols_stat;
	private int rows_stat;
	RGBColor colors;
	private String watermark = null;
	// ADDED BY SAULOCO
	public void generate(String xml, HttpServletResponse resp, String filename){
		parser = new ExcelXmlParser();
		try {
			parser.setXML(xml);
			createExcel(resp);
			setColorProfile();
			headerPrint(parser);
			rowsPrint(parser,resp);
			footerPrint(parser);
			insertHeader(parser,resp);
			insertFooter(parser,resp);
			watermarkPrint(parser);
			outputExcel(resp, filename);
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
// ADDED BY SAULOCO. END
	private void createExcel(HttpServletResponse resp) throws IOException {
		/* Save generated excel to file.
		 * Can be useful for debug output.
		 * */
		/*
		FileOutputStream fos = new FileOutputStream("c:/test.xls");
		wb = Workbook.createWorkbook(fos);
		*/
		wb = Workbook.createWorkbook(resp.getOutputStream());
		sheet = wb.createSheet("Hoja1", 0);
		colors = new RGBColor();
	}
// ADDED BY SAULOCO
	private void outputExcel(HttpServletResponse resp,String filename) throws IOException, WriteException {
		if (filename == null || filename == "")
			filename = "Exportacion";
		resp.setContentType("application/vnd.ms-excel");
		resp.setCharacterEncoding("UTF-8");
		resp.setHeader("Content-Disposition", "attachment;filename="+filename+".xls");
		resp.setHeader("Cache-Control", "max-age=0");
		wb.write();
		wb.close();
	}
// ADDED BY SAULOCO. END
	private void headerPrint(ExcelXmlParser parser) throws RowsExceededException, WriteException, IOException {
		cols = parser.getColumnsInfo("head");
		
		int widths[] = parser.getWidths();
		this.cols_stat = widths.length;
		
		int sumWidth = 0;
		for (int i = 0; i < widths.length; i++) {
			sumWidth += widths[i];
		}
		if (parser.getWithoutHeader() == false) {
			for (int i = 0; i < cols.length; i++) {
				sheet.setRowView(i, 450);
				sheet.getSettings().setVerticalFreeze(i + 1);
				for (int j = 0; j < cols[i].length; j++) {
					sheet.setColumnView(j, widths[j]/scale);
					WritableFont font = new WritableFont(WritableFont.ARIAL, fontSize - 1, WritableFont.BOLD);
					font.setColour(colors.getColor(headerTextColor, wb));
					WritableCellFormat f = new WritableCellFormat (font);
					f.setBackground(colors.getColor(bgColor, wb));
					f.setBorder(Border.ALL, BorderLineStyle.THIN, colors.getColor(lineColor, wb));
					f.setVerticalAlignment(VerticalAlignment.CENTRE);
	
					f.setAlignment(Alignment.CENTRE);
					String name = cols[i][j].getName();
					Label label = new Label(j, i, name, f);
					sheet.addCell(label);
					colsNumber = j;
				}
			}
			headerOffset = cols.length;
			for (int i = 0; i < cols.length; i++) {
				for (int j = 0; j < cols[i].length; j++) {
					int cspan = cols[i][j].getColspan();
					if (cspan > 0) {
						sheet.mergeCells(j, i, j + cspan - 1, i);
					}
					int rspan = cols[i][j].getRowspan();
					if (rspan > 0) {
						sheet.mergeCells(j, i, j, i + rspan - 1);
					}
				}
			}
		}
	}

	private void footerPrint(ExcelXmlParser parser) throws RowsExceededException, WriteException, IOException {
		cols = parser.getColumnsInfo("foot");
		if (cols == null) return;
		if (parser.getWithoutHeader() == false) {
			for (int i = 0; i < cols.length; i++) {
				sheet.setRowView(i + headerOffset, 450);
				for (int j = 0; j < cols[i].length; j++) {
					WritableFont font = new WritableFont(WritableFont.ARIAL, fontSize, WritableFont.BOLD);
					font.setColour(colors.getColor(headerTextColor, wb));
					WritableCellFormat f = new WritableCellFormat (font);
					f.setBackground(colors.getColor(bgColor, wb));
					f.setBorder(Border.ALL, BorderLineStyle.THIN, colors.getColor(lineColor, wb));
					f.setVerticalAlignment(VerticalAlignment.CENTRE);

					f.setAlignment(Alignment.CENTRE);
					String name = cols[i][j].getName();
					Label label = new Label(j, i + headerOffset, name, f);
					sheet.addCell(label);
				}
			}
			for (int i = 0; i < cols.length; i++) {
				for (int j = 0; j < cols[i].length; j++) {
					int cspan = cols[i][j].getColspan();
					if (cspan > 0) {
						sheet.mergeCells(j, headerOffset + i, j + cspan - 1, headerOffset + i);
					}
					int rspan = cols[i][j].getRowspan();
					if (rspan > 0) {
						sheet.mergeCells(j, headerOffset + i, j, headerOffset + i + rspan - 1);
					}
				}
			}
		}
		headerOffset += cols.length;
	}

	private void watermarkPrint(ExcelXmlParser parser) throws WriteException {
		if (watermark == null) return;
		
		WritableFont font = new WritableFont(WritableFont.ARIAL, fontSize, WritableFont.BOLD);
		font.setColour(colors.getColor(watermarkTextColor, wb));
		WritableCellFormat f = new WritableCellFormat (font);
		f.setBorder(Border.ALL, BorderLineStyle.THIN, colors.getColor(lineColor, wb));
		f.setVerticalAlignment(VerticalAlignment.CENTRE);

		f.setAlignment(Alignment.CENTRE);
		Label label = new Label(0, headerOffset, watermark , f);
		sheet.addCell(label);
		sheet.mergeCells(0, headerOffset, colsNumber, headerOffset);
	}

	private void rowsPrint(ExcelXmlParser parser, HttpServletResponse resp) throws WriteException, IOException {
		//do we really need them?
		ExcelRow[] rows = parser.getGridContent();
		if (rows == null) return;
		this.rows_stat = rows.length;
		
		for (int i = 0; i < rows.length; i++) {
			ExcelCell[] cells = rows[i].getCells();
			sheet.setRowView(i + headerOffset, 400);
			for (int j = 0; j < cells.length; j++) {
				// sets cell font
				WritableFont font = new WritableFont(WritableFont.ARIAL, fontSize, (cells[j].getBold()) ? WritableFont.BOLD : WritableFont.NO_BOLD, (cells[j].getItalic()) ? true : false);
				if ((!cells[j].getTextColor().equals(""))&&(parser.getProfile().equals("full_color")))
					font.setColour(colors.getColor(cells[j].getTextColor(), wb));
				else
					font.setColour(colors.getColor(gridTextColor, wb));
				WritableCellFormat f = new WritableCellFormat (font);

				// sets cell background color
				if ((!cells[j].getBgColor().equals(""))&&(parser.getProfile().equals("full_color"))) {
					Colour col = colors.getColor(cells[j].getBgColor(), wb);
					f.setBackground(col);
				} else {
					Colour bg;
					if (i%2 == 1) {
						bg = colors.getColor(scaleTwoColor, wb);
						
					} else {
						bg = colors.getColor(scaleOneColor, wb);
					}
					f.setBackground(bg);
				}

				f.setBorder(Border.ALL, BorderLineStyle.THIN, colors.getColor(lineColor, wb));
				f.setVerticalAlignment(VerticalAlignment.CENTRE);

				String al = cells[j].getAlign();
				if (al == "")
					al = cols[0][j].getAlign();
				if (al.equalsIgnoreCase("left")) {
					f.setAlignment(Alignment.LEFT);
				} else {
					if (al.equalsIgnoreCase("right")) {
						f.setAlignment(Alignment.RIGHT);
					} else {
						f.setAlignment(Alignment.CENTRE);
					}
				}
				try {
					double name = Double.parseDouble(cells[j].getValue());
					Number label = new Number(j, i + headerOffset, name, f);
					sheet.addCell(label);
				} catch (Exception e) {
					String name = cells[j].getValue();
					Label label = new Label(j, i + headerOffset, name, f);
					sheet.addCell(label);
				}
			}
		}
		headerOffset += rows.length;
	}

	private void insertHeader(ExcelXmlParser parser, HttpServletResponse resp) throws IOException, RowsExceededException {
		if (parser.getHeader() == true) {
			sheet.insertRow(0);
			sheet.setRowView(0, 5000);
			File imgFile = new File(pathToImgs + "/header.png");
			WritableImage img = new WritableImage(0, 0, cols[0].length, 1, imgFile);
			sheet.addImage(img);
			headerOffset++;
		}
	}

	private void insertFooter(ExcelXmlParser parser, HttpServletResponse resp) throws IOException, RowsExceededException {
		if (parser.getFooter() == true) {
			sheet.setRowView(headerOffset, 5000);
			File imgFile = new File(pathToImgs + "/footer.png");
			WritableImage img = new WritableImage(0, headerOffset, cols[0].length, 1, imgFile);
			sheet.addImage(img);
		}
	}

	public int getColsStat() {
		return this.cols_stat;
	}
	
	public int getRowsStat() {
		return this.rows_stat;
	}

	private void setColorProfile() {
		String profile = parser.getProfile();
		if ((profile.equalsIgnoreCase("color"))||profile.equalsIgnoreCase("full_color")) {
			bgColor = "D1E5FE";
			lineColor = "A4BED4";
			headerTextColor = "000000";
			scaleOneColor = "FFFFFF";
			scaleTwoColor = "E3EFFF";
			gridTextColor = "000000";
			watermarkTextColor = "8b8b8b";
		} else {
			if (profile.equalsIgnoreCase("gray")) {
				bgColor = "E3E3E3";
				lineColor = "B8B8B8";
				headerTextColor = "000000";
				scaleOneColor = "FFFFFF";
				scaleTwoColor = "EDEDED";
				gridTextColor = "000000";
				watermarkTextColor = "8b8b8b";
			} else {
				bgColor = "FFFFFF";
				lineColor = "000000";
				headerTextColor = "000000";
				scaleOneColor = "FFFFFF";
				scaleTwoColor = "FFFFFF";
				gridTextColor = "000000";
				watermarkTextColor = "000000";
			}
		}
	}
	
	public void setWatermark(String mark) {
		watermark = mark;	
	}
	
	public void setFontSize(int fontsize) {
		this.fontSize = fontsize;
	}

// ADDED BY SAULOCO. END
	public void generate(String xml, HttpServletResponse resp){
		parser = new ExcelXmlParser();
		try {
			parser.setXML(xml);
			createExcel(resp);
			setColorProfile();
			headerPrint(parser);
			rowsPrint(parser,resp);
			footerPrint(parser);
			insertHeader(parser,resp);
			insertFooter(parser,resp);
			watermarkPrint(parser);
			outputExcel(resp);
		} catch (Throwable e) {
			e.printStackTrace();
		}
	
	}
	private void outputExcel(HttpServletResponse resp) throws IOException, WriteException {
		resp.setContentType("application/vnd.ms-excel");
		resp.setCharacterEncoding("UTF-8");
		resp.setHeader("Content-Disposition", "attachment;filename=grid.xls");
		resp.setHeader("Cache-Control", "max-age=0");
		wb.write();
		wb.close();
	}
// ADDED BY SAULOCO. END
}

:frowning: I build it, replace the .class files but it still not working…
And I cant receive any console’s result or some return…

What is wrong with this code? aside who wrote it!

Hi,
have a look at file WEB-INF/src/com/dhtmlx/xml2excel/ExcelWriter.java, method outputExcel.
It must take parameter filename and use it to produce excel:

private void outputExcel(HttpServletResponse resp, String filename) throws IOException, WriteException {
      resp.setContentType("application/vnd.ms-excel");
      resp.setCharacterEncoding("UTF-8");
      resp.setHeader("Content-Disposition", "attachment;filename=" + filename);
      resp.setHeader("Cache-Control", "max-age=0");
      wb.write();
      wb.close();
   }

Ok, but there are two method named ‘outputExcel’.
The last is original, but the other is modified by me. And it has the parameter just like you said.
The ‘generate’ method is repeated too, but have different parameters.
Exists a name to explain it in Java, when you have two methods named equals between them but have different parameters or returns different values. “Sobrecarga” would be in spanish, Do it named ‘overload’ in english?
Please, keep helping me… I cant found the error by my own yet!

Hi,
you code looks correct.
It’s weird that it doesn’t work.
Could you describe more in details how it doesn’t work: exception or default file name?
If it uses default file name then make sure that you’ve updated file correctly. Also be attentive, there are two files with the same name in package: PDFGenerator.java.

Yes, you right, @radyno but it still not working.
I’ve modified both files, because I dont know how it really works, I think that one is never used, but even I’ve modified both files.

I think I’m near to finish this feature, and reading in this forum, I’ve found that a lot of people ask for it, if it works I will be proud to share this code with you (if you want) to improve the solution.

Hi,
please describe how it doesn’t work.
Does it open new page (especially for pdf, excel uses silent downloading)?
Also, please make sure that you call export correctly (with additional parameter ‘filename’).