How to set the default opening method of files with suffix (XLS or xlsx or CSV) in idea

Answered

I've developed a plug-in before, after selecting a file with the suffix (XLS or xlsx or CSV). Right click the mouse and select "open as ExcelReader" to display the file content in the toolwindow.

See https://plugins.jetbrains.com/plugin/14722-excelreader 

But now, Microsoft office is still the default opening method.

The effect I want to achieve is to select a file (the suffix is XLS or xlsx or CSV), and then automatically open the toolwindow and display its contents.

In other words, you need to right-click and select "open as ExcelReader" to display the content.

But now: just select the file and you can do the same as ExcelReader.

14 comments
Comment actions Permalink

Current effect

0
Comment actions Permalink

I wanted effect

0
Comment actions Permalink

First of all, I'd suggest changing the action name to "Open in ExcelReader".

Such XLS-like files are opened in the native applications because they're not explicitly registered in the IDE - so finally there is INativeFileType assigned to them.

Because of that, FileNavigator with its logic is passing it to the NativeFileType.openAssociatedApplication(VirtualFile) method.

The only way of intercepting this flow and avoiding the native application to be run is by registering a custom FileType for your files. You can even consider extending the existing NativeFileType and override just the methods responsible for the open action.

0
Comment actions Permalink

Ok, I got it. Thanks Jakub!:D

0
Comment actions Permalink

Yesterday, I try to fix this problem.

First, I create a new java file named 「MyExcelNativeType」

======================== MyExcelNativeType.java ========================

public class MyExcelNativeFileType implements INativeFileType {

public static final MyExcelNativeFileType INSTANCE = new MyExcelNativeFileType();

public MyExcelNativeFileType() {

}

@Override
public boolean openFileInAssociatedApplication(Project project, @NotNull VirtualFile virtualFile) {
return openInExcelReader(virtualFile);
}

@Override
public boolean useNativeIcon() {
return true;
}

@NotNull
@Override
public String getName() {
return "MyNative";
}

@NotNull
@Override
public String getDisplayName() {
return "MyNativeDisplayName";
}

@Nls(capitalization = Nls.Capitalization.Sentence)
@NotNull
@Override
public String getDescription() {
return IdeBundle.message("native.filetype.description");
}

@NotNull
@Override
public String getDefaultExtension() {
return "";
}

@Nullable
@Override
public Icon getIcon() {
return AllIcons.FileTypes.Custom;
}

@Override
public boolean isBinary() {
return true;
}

@Override
public boolean isReadOnly() {
return false;
}

@Nullable
@Override
public String getCharset(@NotNull VirtualFile virtualFile, @NotNull byte[] bytes) {
return null;
}

public boolean openInExcelReader(@NotNull final VirtualFile file){
System.out.println(file.getExtension());
return true;
}

}

Secondly, register in the plugin.xml

======================== plugin.xml ========================

...
<extensions defaultExtensionNs="com.intellij">
<fileType name="MyNative" implementationClass="com.chesterccw.excelreader.MyExcelNativeFileType" fieldName="INSTANCE"
extensions="xls;xlsx;csv"/>
</extensions>
...

But it's strange that the openfileinassociatedapplication method in the newly created one was not called. I added a breakpoint here, but I didn't find it was called. Then I was there com.intellij.openapi.fileTypes.NativeFileType Class's openfileinassociatedapplication method added a breakpoint. I found that when opening a file, the openfileinassociatedapplication method of the nativefiletype class was called, which was not written by myself.

0
Comment actions Permalink

You have forgotten to provide the INSTANCE field, which you try to refer in the <fieldType> declaration. Because of that, your file type is considered as a PlainText, and even icon is not set to the native one but a regular text file. Check the NativeFileType.java#L20

0
Comment actions Permalink

Thanks, Jakub. But I'm sorry,I don't quite understand the replay "You have forgotten to provide the INSTANCE field". 

Do you mean, except in plugin.xml to register filetype in <extensions >... </extensions>, i also need to register filetType in actionPerformed method of myAction?

This is my Action code

====================== ExcelReaderAction.java ======================

public class ExcelReaderAction extends AnAction {

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
FileTypeManager.getInstance().associateExtension(MyExcelNativeFileType.INSTANCE,"xls;xlsx;csv");
Data data = new ResolveData(e).resolve();
Project project = e.getData(PlatformDataKeys.PROJECT);
if(project == null){
return;
}
new OpenFile(data,project).open();
}

public static class Data {
public String title;
public Vector<String> header = new Vector<>();
public Vector<Vector<Object>> rows = new Vector<>();
}
}

In #21,i registered by FileTypeManager.associateExtension() method. But it's not working.

0
Comment actions Permalink

Ah, I didn't notice that you already had it.

However, I've used your code - MyExcelNativeFileType class and fileType definition in plugin.xml and it stops correctly on the breakpoint set in openFileInAssociatedApplication method. There is no need to register it using FileTypeManager.

0
Comment actions Permalink

That's strange. I don't know if it's related to the development environment

My environment:

  • JDK   :  1.8.0_211
  • IDEA :2020.1
  • IDEA Plugin SDK :IntelliJ IDEA IU-201.7223.91

Cannot enter  MyExcelNativeFiletype.openFileInAssociatedApplication(VirtualFile) function,it enter the same function in `com.intellij.openapi.fileTypes.NativeFileType`, Not mine. 

So, could you tell me your development environment. Or, what do you think might be the problem? Because it's normal on your computer, but it's not normal on my side. I can't get to the breakpoint in `MyExcelNativeFiletype.openFileInAssociatedApplication`...

0
Comment actions Permalink

Can I ask you to share a minimal reproducible project so I can verify it locally?

0
Comment actions Permalink

Thank you very much. I have sent you an invitation on GitHub.

0
Comment actions Permalink

James, the preferred way of creating a project these days is to use Gradle setup. I have migrated your project to Gradle in v2.0.1-Gradle branch, and it appeared that your implementation was working as expected.

FYI - if IntelliJ will mark some imports red, make sure that you have set Java 1.8 as the SDK.

0
Comment actions Permalink

I see it, Jakub. Thank you. But the embarrassment is that I still have the same situation as yesterday. The breakpoint can't enter the openFileinAssociated application of my own class MyExcelNativeFiletype. It's always enter the `com.intellij.openapi.fileTypes.NativeFileType`.

em...I'll try again. Thank you!

0
Comment actions Permalink

Now that it's OK, I can enter my own filetype class. It is estimated that the configuration of gradle environment is not correct. Now it's settled. Thank you, Jakub!

0

Please sign in to leave a comment.