How do I open multiple Excel files using Ruby script? - ruby

I am working on writing a ruby script to iterate through a file containing a list of file paths to open in Microsoft Excel. I read the file like this:
file_names = IO.readlines('D:\TEST_1\file_names.txt')
Next, I create an array of file names from each line of the parsed file (thus containing an array of file paths). Finally, I loop through that array with the following code, to open the documents:
require 'win32ole'
xl = WIN32OLE.new('Excel.Application')
xl.Visible = 1
file_names.each do |file_name|
wb1=xl.Workbooks.Open(file_name)
ws1=wb1.worksheets(1)
end
That first call to parse file_names.txt produces this exception, which I am having difficulty understanding:
Test4.rb:6:in 'method_missing'
OLE error code:800A03EC in Microsoft Office
Excel 'D:\Test_1\1.xlsx' couldnot be found. Check the spelling of
the file name, and verify that the file location is correct.
if you are trying to open the file from your list most recently used
files, make sure that the file has not been renamed, moved or deleted
HR Error code : 0x80020009 Exception occurred. from Test4.rb:6:in
'block in ' from Test4.rb:5:in 'each' from Test4.rb:5:in
''
This error does not appear when I pass a single file name (instead of a file path) as my parameter - so why do I get it here? Any help would be much appreciated.

At first look you are not using the variable "file_name" but a symbol :file_name.
file_array.each do |file_name|
wb1=xl.Workbooks.Open(file_name)
ws1=wb1.worksheets(1)
end

Related

Creating Text Files From a Loop

I am using the Watson document conversion service. I have a set of .html files that I want to pass into the Watson API. I created two lists the first one (File_Name_List) contains the names of the .html files and the second (File_Name_List_TXT) contains the names of the .txt files I want the output of the Watson service to write to. Everytime I run the code below it gives me the following error: ValueError: I/O operation on closed file. I cannot figure out what the issue is - any help would be appreciated.
for file in File_Name_List:
for file_txt in File_Name_List_TXT:
f = open(file_txt,'w')
with open(join(dirname(__file__), file), 'r') as document: config = {'conversion_target': DocumentConversionV1.NORMALIZED_TEXT}
f.write(str(document_conversion.convert_document(document=document, config=config, media_type='text/plain').content).lower())
f.close()

Command Prompt error since i am using a generic path to open an excel file

Command Prompt its not working since i am using a generic path to open a excel file. Here is the error message:
T:\PointOfSale\Projects\Automated Testing\TASWeb\TP\TP_Branch>ruby -rubygems Tes
tTP_UK.rb
TestTP_UK.rb:19:in 'method_missing': (in OLE method `Open': )(WIN32OLERuntimeEr
ror)
OLE error code:800A03EC in Microsoft Excel
'./../../../MasterFile.xls' could not be found. Check the spelling of the
file name, and verify that the file location is correct.
If you are trying to open the file from your list of most recently used files, m
ake sure that the file has not been renamed, moved, or deleted.
HRESULT error code:0x80020009
Exception occurred.
from TestTP_UK.rb:19:in `'
enter code here'
Generic path code
excel = WIN32OLE::new("excel.Application")
path = "#{File.dirname(__FILE__)}/../../../MasterFile.xls"
workbook = excel.Workbooks.Open(path)
worksheet = workbook.WorkSheets(1) # Get first workbook
site = worksheet.Range('A2').Value # Get the value at cell in worksheet.
workbook.Close
excel.Quit
Any Ideas
I believe you need to use an absolute path rather than a relative path when opening the file:
path = File.expand_path("../../../../MasterFile.xls", __FILE__)
Note that you will also need an additional '..' when using expand_path, since the first '..' is going back from the file.

Save twitter search result to JSON file

I am using twitter ruby gem to fetch twitter search result. The example code from Github extracts the information from search result.I am wondering how to save the search result, which is JSON i think, to a separate JSON file.
Here is part of the example code:
results = #search.perform("$aaa", 1000)
aFile = File.new("data.txt", "w")
results.map do |status|
myStr="#{status.from_user}: #{status.text} #{status.created_at}"
aFile.write(myStr)
aFile.write("\n")
end
Is there any way to save all the search result to a separate JSON file instead of writing strings to a file?
Thanks in advance.
If you want to save to a file all you need to do is open the file, write it it, then close it:
File.open("myFileName.txt", "a") do |mFile|
mFile.syswrite("Your content here")
mFile.close
end
When you use open you will create the file if it doesn't exist.
One thing to be aware of is that there are different ways to open file, of which will determine where the program writes to. The "a" indicates that it will append everything you write to the file, to the end of the current content.
Here is some of the options:
r Read-only mode. The file pointer is placed at the beginning of the file. This is the default mode.
r+ Read-write mode. The file pointer will be at the beginning of the file.
w Write-only mode. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing.
w+ Read-write mode. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing.
a Write-only mode. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing.
a+ Read and write mode. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing.
So in your case, you would want to pull out the data you want to save, then write it to a file as I have shown. You can also specify file paths by doing:
File.open("/the/path/to/yourfile/myFileName.txt", "a") do |mFile|
mFile.syswrite("Your content here")
mFile.close
end
Another thing to be aware of is that open does not create directories, so you will either need to create directories yourself, or you can do it with your program. Here is a link that is helpful for file input/output:
http://www.tutorialspoint.com/ruby/ruby_input_output.htm

Convert a PDF to .txt gives me an empty .txt file

Hi I'm trying to read a pdf in Ruby, first of all I want to convert it into a txt. path is the path to the PDF, The point is that I get a .txt file empty, and as someone told me is a pdftotext problem, but I don't know how to fix it.
spec = path.sub(/\.pdf$/, '')
`pdftotext #{spec}.pdf`
file = File.new("#{spec}.txt", "w+")
text = []
file.readlines.each do |l|
if l.length > 0
text << l
Rails.logger.info l
end
end
file.close
What's wrong with my code? Thanks!
It's not possible to extract text from every PDF. Some PDF files use a font encoding that makes it impossible to extract text with simple tools such as pdftotext (and some PDF files are even completely immune to direct text extraction with any tool known to me -- in these cases you'll have to apply OCR first to have a chance to extract text...).
So if you test your code with the same "weird" PDF file all the time, it may well happen that you're getting frustrated over your code while in reality the fault lies with the PDF.
First make sure that the commandline usage of pdftotxt works well with a given PDF, then test (and develop further) your code with that PDF.
The problem is you are opening the file in write ("w") mode, whuch truncates the file. You can see a table of file modes and what they mean at http://ruby-doc.org/core-1.9.3/IO.html.
Try something like this, it uses a pdftotext option to send the text to stdout to avoid creating a temporary file and uses blocks for more idiomatic ruby.
text = `pdftotext #{path} -`
text.split.select { |line|
line.length > 0
}.each { |line|
Rails.logger.info(line)
}
You would need to open the txt file with write permission.
file = File.new("#{spec}.txt", "w")
You could consult How to create a file in Ruby
Update: your code is not complete and looks buggy.
Cant say what is path
Looks like you are trying to read the text file to which you intend to write file.readlines.each
spell check length you have it l.lenght
You may want to paste the actual code.
Check this gist https://gist.github.com/4160587
As mentioned, your code is not working because you are reading and writing to the same file.
Example
Ruby code file_write.rb to do the file write operation
pdf_file = File.open("in.txt")
output_file = File.open("out.txt", "w") # file to which you want to write
#iterate over input file and write the content to output file
pdf_file.readlines.each do |l|
output_file.puts(l)
end
output_file.close
pdf_file.close
Sample txt file in.txt
Some text in file
Another line of text
1. Line 1
2. Not really line 2
Once your run file_write.rb you should see new file called out.txt with same content as in.txt You could change the content of input file if you want. In your case you would use pdf reader to get the content and write it to the text file. Basically first line of the code will change.

Parsing a Zip file and extracting records from text files

I am really new to Ruby and could use some help with a program. I need to open a zip file that contains multiple text files that has many rows of data (eg.)
CDI|3|3|20100515000000|20100515153000|2008|XXXXX4791|0.00|0.00
CDI|3|3|20100515000000|20100515153000|2008|XXXXX5648|0.00|0.00
CHO|3|3|20100515000000|20100515153000|2114|XXXXX3276|0.00|0.00
CHO|3|3|20100515000000|20100515153000|2114|XXXXX4342|0.00|0.00
MITR|3|3|20100515000000|20100515153000|0000|XXXXX7832|0.00|0.00
HR|3|3|20100515000000|20100515153000|1114|XXXXX0238|0.00|0.00
I first need to extract the zip file, read the text files located in the zip file and write only the complete rows that start with (CDI and CHO) to two output files, one for the rows of data starting with CDI and one for the rows of data starting with CHO (basically parsing the file). I have to do it with Ruby and possibly try to set the program to an auto function for arrival of continuous zip files of the same stature. I completely appreciate any advice, direction or help via some sample anyone can give.
One means is using the ZipFile library.
require 'zip/zip'
# To open the zip file and pass each entry to a block
Zip::ZipFile.foreach(path_to_zip) do |text_file|
# Read from entry, turn String into Array, and pass to block
text_file.read.split("\n").each do |line|
if line.start_with?("CDI") || line.start_with?("CHO")
# Do something
end
end
end
I'm not sure if I entirely follow your question. For starters, if you're looking to unzip files using Ruby, check out this question. Once you've got the file unzipped to a readable format, you can try something along these lines to print to the two separate outputs:
cdi_output = File.open("cdiout.txt", "a") # Open an output file for CDI
cho_output = File.open("choout.txt", "a") # Open an output file for CHO
File.open("text.txt", "r") do |f| # Open the input file
while line = f.gets # Read each line in the input
cdi_output.puts line if /^CDI/ =~ line # Print if line starts with CDI
cho_output.puts line if /^CHO/ =~ line # Print if line starts with CHO
end
end
cdi_output.close # Close cdi_output file
cho_output.close # Close cho_output file

Resources