I have an excel workbook I need to open from python in a writable mode. The workbook is set up to have the prompt for a read only recommendation and this cannot be removed.
I am using the following:
import win32com.client
xl=win32com.client.Dispatch("Excel.Application")
filepath = 'C:\Users\FullFilePath.xlsm'
xl.Workbooks.Open(Filename=filepath, ReadOnly=False, IgnoreReadOnlyRecommended=True)
It opens the file, but it's still popping up the dialog asking if I want to open in read only. Is it possible to cancel that dialog?
Use instead:
xl = win32com.client.DispatchEx('Excel.Application')
This works without a dialog box for me.
Related
I'm using ORA_EXCEL PL/SQL API to create custom Excel files. I have it set so that when clicking a button it calls a GENERATE_EXCEL_PROCESS via a page submit (tried both Processing and After Submit processing points) and builds the file and saves it to a Blob variable (confirmed file creation is working in separate test writing file to an Oracle Directory).
My goal is to generate the Excel file in PLSQL, save to a blob and then display a download dialog for users to save the excel file locally similarly to the native Download link that Classic reports allow you to turn on declaratively.
When run I get a weird APEX error, that I only found by turning Full Trace mode on in debugging. I've included the code below, but I do not know what it means to troubleshoot further. It looks like I get a response back of Blob looking at network tab in devtools.
PROCEDURE apex_file_download(
p_file_name VARCHAR2,
p_generated_file BLOB,
p_file_type VARCHAR2 DEFAULT 'EXCEL'
) IS
vcMimeType VARCHAR2(1000);
blob_file BLOB;
blob_size INTEGER;
BEGIN
CASE p_file_type
WHEN 'EXCEL' THEN
vcMimeType := 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
END CASE;
blob_file := p_generated_file;
-- Get BLOB size
blob_size := dbms_lob.getlength(blob_file);
-- Print content type header for MS Excel
owa_util.mime_header(vcMimeType, FALSE, NULL);
-- Put BLOB size header
htp.p('Content-length: '|| blob_size);
-- Set file name that will be suggested when download dialog appears
htp.p('Content-Disposition: attachment; filename="'||p_file_name||'"');
-- Close header
owa_util.http_header_close;
-- Download BLOB
wpg_docload.download_file(blob_file);
apex_application.stop_apex_engine;
EXCEPTION
WHEN apex_application.e_stop_apex_engine THEN
NULL;
WHEN OTHERS THEN
RAISE;
END;
END;
Someone provided a solution for me in the Oracle forum. I'm not sure why this works and wish I had a better understanding of the error and how this fixes it, but posting here in case others have the same problem.
Oracle Forums Solution
I'm writing a web application that generates reports from a local database. I want to generate an excel spreadsheet and immediately cause the user to download it. However, when I try to return the file via HttpResponse, I can not open the file. However, if I try to open the file in storage, the file opens perfectly fine.
This is using Django 2.1 (for database reasons, I'm not using 2.2) and I'm generating the file with xlrd. There is another excel spreadsheet that will need to be generated and downloaded that uses the openpyxl library (both libraries serve very distinct purposes IMO).
This spreadsheet is not very large (5x6 column s xrows).
I've looked at other similar stack overflow questions and followed their instructions. Specifically, I am talking about this answer:
https://stackoverflow.com/a/36394206/6411417
As you can see in my code, the logic is nearly the same and yet I can not open the downloaded excel spreadsheets. The only difference is that my file name is generated when the file is generated and returned into the file_name variable.
def make_lrm_summary_file(request):
file_path = make_lrm_summary()
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
response['Content-Disposition'] = f'inline; filename="{ os.path.basename(file_path) }"'
return response
raise Http404
Again, the file is properly generated and stored on my server but the download itself is providing an excel file that can not be opened. Specifically, I get the error message:
EXCEL.EXE - Application Error | The application was unable to start correctly (0x0000005). Click OK to close the application.
The following code snippet sends PostScript content (saved in pBuf buffer) to a CutePDF printer:
if (OpenPrinter(printerName, &hPrinter, NULL))
{
DOC_INFO_1 di1;
di1.pDatatype = L"RAW";
di1.pDocName = L"Raw print document";
di1.pOutputFile = NULL;
StartDocPrinter(hPrinter, 1, (LPBYTE)&di1);
StartPagePrinter(hPrinter);
DWORD dwWritten = 0;
WritePrinter(hPrinter, pBuf, dwBufSize, &dwWritten);
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
}
During the execution of this code, a dialog appears where I specify the name of the output file (e.g. D:/out.pdf), after that the pdf file is generated. So far so good. The problems begin when I'm trying to avoid the filename specifying step by changing Line 4 of the snippet:
di1.pOutputFile = L"D:/out.pdf";
Such code doesn't show the dialog during its execution (as expected), but the result D:/out.pdf isn't a pdf file, it's a copy of the PostScript file sent to the printer (copy of the contents of pBuf buffer). PDF Writer behaves in the same way. Why do PDF printers behave in this way and how can I achieve the needed behaviour (generate PDF file without specifying its name in UI)?
The Windows print system behaves this way, because, to be blunt, that's how its supposed to behave. If you specify a filename at that point then the print system sends the output to that file. If you don't specify a filename then it proceeds to normal processing.
Normally you would send the printer driver output to a port, and in the case of PDF printers a custom port monitor would pick up the output (PostScript in this case) and process it further. For PDF printers they send the PostScript on to a process which converts the PostScript to PDF (almost always using Ghostscript, though the Adobe print to PDF tools work the same way).
If you want to alter the output of the PDF process (ie write it to a different file), then you need to alter the way the port monitor works, not the way the print subsystem works, which is what your code is currently doing. By setting a filename where you are, you are simply short-circuiting the process, never invoking the port monitor, which is why the 'save file' dialog does not appear, and why the output is PostScript.
There may be a way of specifying the output file documented for the specific PDF printer you are using. If not, then for open source products (and if GS is built in they should be GPL licensed) you can request a copy of the source code for the product and alter it to suit yourself.
Alternatively, you can pick up a copy of Ghostscript and RedMon (open source Port Monitor) and create your own tool for doing the same job.
Simply put, I double click on image1 in its file and it opens. I run the code bellow to open image1 and nothing comes up. So I go into the file with image1 again, double click on it, and windows photo viewer said, "Windows Photo Viewer can't display this picture because the file is empty." I did this with two other test images and the same thing is happening. Nothing important has been lost but this method seems to be erasing whichever file it tries to open and I'm very curious as to why and how I can fix it.
#include <iostream>
#include <fstream>
#include <chrono>
#include <thread>
void main()
{
std::ofstream imagetest;
imagetest.open("C:\\Users\\Filepath\\image1.jpg");
std::chrono::milliseconds dura(2000);
std::this_thread::sleep_for(dura);//Kept the sleep in because I didn't know if having the console up would affect the file/image from opening.
}
C++ is at lower level than scripts. open does not mean START.
You will have to execute a batch script with START C:\Users\Filepath\image1.jpg.
Or to learn many more libraries to do that in C++...
ofstream stands for “output file stream”. In addition to creating files that doesn’t exist, it also erases the contents of files that do exist. So you are opening an existing file for writing, and blowing away its contents in the process. You probably want ifstream, “input file stream”, for reading.
If you want to “open” the file in the sense of launching the default Windows application to read the file, you can use the Windows start command via system:
system("start \"C:\\Users\\Filepath\\image1.jpg\"");
Or the Windows ShellExecute API:
#include <windows.h>
ShellExecute(
NULL,
"open",
"C:\\Users\\Filepath\\image1.jpg",
NULL,
NULL,
SW_SHOWNORMAL
);
First,
std::ofstream imagetest;
is using the kernel to open the file for reading the file data..
this is probably what is corrupting the file from "opening" when you double click on it in windows
if you want to have windows open the image for viewing using the default application then you need a different method call because ofstream.open is not what you want.
try:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx
ShellExecute(NULL,"open","C:\\Users\\Filepath\\image1.jpg",NULL,NULL,SW_SHOW);
If you open a file stream for WRITE, then it will wipe all the content of that file, just like when you do that on a txt file. So you would always want to open the stream for read mode if you don't want that to happen
I am creating a simple logging program. When a user enters log some_file into the console, the program currently simply receives some basic input from cin, and records it into some_file.
However, instead of implementing my own editor with cin, I'd like to open the Nano editor and let the user edit his message there.
Then, when the message is complete, I'd like my C++ logger to receive it as a string and carry on.
This is exactly what git does on commits.
How can I achieve this?
(Preferably without using tools such as expect, just raw C++ code.)
Most editors expect to work with normal files, so you'd typically create a temporary file, then pass the name of that file to the editor on its command line. When the editor returns, you copy the content from the temporary file into your log, then destroy the file.
If you want to use the Nano editor then you need to run the system() function to invoke Nano with a temporary file. Then remove the file later..
std::string filename = "/tmp/.out." + std::to_string(getpid());
std::string cmd = "/bin/nano " + filename
system(cmd.c_str());
// read from filename
unlink(filename.c_str());
Update
If using tmpnam() as suggested by DevSolar
char filename[L_tmpnam];
tmpnam(filename);
std::string cmd = "/bin/nano " + filename
system(cmd.c_str());
unlink(filename);
what about open a file(passing file name to the editor), save and then read it from your program? I've always thought git works the same way.