用java 操作word 使其变成图片和文字对齐 (最好是操作页脚)图片和文字都需要新插入进去word的
word中对齐的方法:
但是java怎么这样操作就不会了
问题跟这个同志的一样,但是他的解答看不懂,希望哥们回答的时候直接上代码和效果截图,感谢!
https://ask.csdn.net/questions/7762178
这是我自己的代码:
public R addSignature() throws Exception {
Document doc = new Document("D:/sample.docx");
//获取第一节
Section sec = doc.getSections().get(0);
//删除页脚
sec.getHeadersFooters().getFooter().getChildObjects().clear();
HeaderFooter footer = sec.getHeadersFooters().getFooter();
Paragraph fpara= footer.addParagraph();
fpara.appendText("试验:");
fpara.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
DocPicture pic =fpara.appendPicture("D:/图片1.png");
pic.setVerticalAlignment(ShapeVerticalAlignment.Center);
pic.setHorizontalAlignment(ShapeHorizontalAlignment.Center);
doc.saveToFile("D:/sample.docx", FileFormat.Docx_2013);
return R.ok();
}
这是运行的结果
你图上的文本对齐方式是专门针对中文版式的设置,感觉目前很少有类库支持这个。但是你可以用另一个替代方法,就是表格来实现类似效果。
下面是实现代码和结果,如果有帮到你,希望能采纳:
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.fields.TextRange;
public class AddFooter {
public static void main(String[] args) {
//加载Word文档
Document doc= new Document("test.docx");
//获取文档第一个节
Section sec = doc.getSections().get(0);
//获取该节的页脚
HeaderFooter footer = sec.getHeadersFooters().getFooter();
//创建一个1行2列的表格
Table table = footer.addTable();
table.resetCells(1,2);
//获取第一行
TableRow row = table.getRows().get(0);
//添加段落到第一个单元格
Paragraph paragraph = row.getCells().get(0).addParagraph();
//添加文本到段落并设置字体
TextRange text = paragraph.appendText("试验");
text.getCharacterFormat().setFontName("宋体");
//设置文本水平对齐方式为右对齐
paragraph.getFormat().setHorizontalAlignment(HorizontalAlignment.Right);
//设置文本垂直对齐方式为居中对齐
row.getCells().get(0).getCellFormat().setVerticalAlignment(VerticalAlignment.Middle);
//添加图片到第二个单元格
row.getCells().get(1).addParagraph().appendPicture("logo.png");
//移除表格边框
table.getTableFormat().getBorders().setBorderType(BorderStyle.None);
//设置表格对齐方式为居中(即文字和图片显示在页脚中部)
table.getTableFormat().setHorizontalAlignment(RowAlignment.Center);
//自动调整表格宽度以适应内容
table.autoFit(AutoFitBehaviorType.Auto_Fit_To_Contents);
//保存文档
doc.saveToFile("设置页脚.docx", FileFormat.Docx_2013);
doc.close();
}
}
楼主看看这个链接呢:https://www.geeksforgeeks.org/java-program-to-align-the-text-in-a-word-document/
这种需求都是定制性开发,我觉得确实15程序员兼职也不会考虑的,你可以先去尝试链接代码把运行结果告诉我们,我们在帮助你排错代替直接给你代码结果,这是gpt的任务,而不是程序员愿意做的事
设置居中显示
paragraph.setAlignment(ParagraphAlignment.CENTER); 图片和文件居中设置有没有试过。
可以用poi库操作
不知道你这个问题是否已经解决, 如果还没有解决的话:深入探究错题,每个重点新开一篇文章,并在此文章中添加新文章链接(待完成)
编译Java程序的命令是:
A、appletviewer √B、javac
×C、java D、javadoc
为了使一个名为MyClass的public类成功编译,需满足以下哪些条件?
请选择一个正确答案:
(1)MyClass类中必须定义一个正确的main()方法。
√(2) MyClass类必须定义在MyClass.java源文件中。
//(public类的文件名必须和类名一致)
(3) MyClass类必须定义在MyClass包中。
×(4) MyClass类必须被导入。
给出以下代码,请问采取命令行方式java Example I like tests运行该程序,结果是什么?
请选择一个正确答案:
class Example {
public static void main(String[] args) {
System.out.println(args[l]);
}
}
(1)打印输出MyProg
×(2) 打印输出I
√(3) 打印输出Iike // args[1]表示第2个参数,参数用空格分开
(4) 打印输出3
(5) 打印输出4
(6) 打印输出null
class Example {
public static void main(String[] args) {
System.out.println(args[4]);
}
}
请选择一个正确答案:
×(1) 打印输出All
(2) 打印输出For
(3) 打印输出Justice
(4)没有输出
√(5)运行期(Runtime)错误 // 数组越界
(6)打印输出Metallica
Java语言中,负责并发管理的机制是
A.垃圾回收
×B.虚拟机
C.代码安全
√D.多线程
分析如下的Java代码段,()编译没有异常和错误
a) byte b=257;
b) boolean b=null;
×c) float f=1.3; // float 类型初始化数据要加f, 不加f默认为double型
√d) int i=12;
以下哪个不是Java的基本数据类型
A、int √B、Boolean C、float D、char
下列关于基本数据类型的取值范围的描述中,正确的一个是
×(A)byte类型的取值范围是-128~128 // -128~127
√(B)boolean类型的取值范围是真或假
(C )char类型的取值范围是0~65536
(D)short类型的取值范围是-32767~32767
设有类型定义short i=32; long j=64; 下面赋值语句中不正确的一个是
(A)j=i; √(B)i=j; ©i=(short)j; (D)j=(long)i;
// 低级赋给高级自动完成转换
下列说法中,正确的一项是
(A)字符串"\abcd"的长度为6
×(B)False是Java的保留字 // false
×(C )123.45L代表单精度浮点型 // 123.45f
√(D)False是合法的Java标识符
下列哪些语句关于Java内存回收的说明是正确的?
A、程序员必须创建一个线程来释放内存
√B、内存回收程序负责释放无用内存
C、内存回收程序允许程序员直接释放内存
D、内存回收程序可以在指定的时间释放内存对象
请问,如何强制垃圾回收一个指定的对象?
请选择一个正确答案:
(1)调用finalized()方法。
(2)废弃所有对象的引用。
(3)使用所有的内存
√(4)无法强制垃圾回收一个指定的对象。
给出以下代码,请问该程序的运行结果是什么?
public class Example {
int cube(int theNum) {
return theNum * theNum * theNum;
}
public static void main(String args[]) {
int a = 5;
System.out.println(cube(a));
}
}
请选择一个正确答案:
A. 代码编译失败,因为方法cube()不是公有方法
B. √代码编译失败,因为方法cube()不是静态方法。 // 程序通过创建对象来运行
C. 代码编译成功,但运行期抛出异常。
D. ×打印输出125。
下列标识符(名字)命名原则中,正确的是( )。
A.类名的首字母小写 ×B.接口名的首字母小写(大驼峰命名法,首字母大写)
√C.常量全部大写 D.变量名和方法名的首字母大写
下列关于Java语言中要使用的一个变量,不正确的是:
A、在Java程序中要使用一个变量,必须先对其进行声明;
×B、变量声明语句可以在程序的任何地方,只要在变量使用前就可以;
C、变量不可以在其作用域之外使用;
√D、局部变量在使用之前可以不初始化,系统使用默认的初始值;
// 局部变量必须初始化,成员变量可不初始化
下列关于变量作用域的说法中,正确的一项是:
×A、方法参数的作用域是方法外部代码段; // 方法内部代码段
√B、全局变量的作用域是整个类;
C、局部变量的作用域是整个类; // 方法内
D、类变量的作用域是类的某个方法; // 是该类
给定如下Java程序,编译运行时,将在()语句出现错误
public class Test {
public static void main(String args[]) {
int i = 0; // a语句
for (; i < 10; i++) // b语句
{
if (i > 5) {
String test = "hello"; // c语句
}
}
System.out.println(test); // d语句(局部变量在代码块外失去作用)
}
}
a) a b) b c) c √d) d
为某类的一个无形式参数无返回值的方法method书写方法头,使得使用类名作为前缀就可以调用它,该方法头的形式为( )。
√A. static void method( ) // 类方法 B. public void method( )
C. final void method( ) // 不可继承 D. abstract void method( )
有关实例方法和类方法的描述正确的是()
√(A).实例方法能对类变量和实例变量操作
(B).实例方法只能对类变量操作
( C ).实例方法只能对实例变量操作
×(D).类方法能对类变量和实例变量操作 // 不能操作实例变量
给定一个Java程序的方法结构如下;以下方法体实现语句正确的是( )。(选择两项)
public Integer change( int i) {
}
A、Integer int =new Integer( i) ;
return int;
B、Integer t = Integer.valueOf( i) ;
√C、return new Integer( i) ; // 需返回方法前指定的类型
D、return i;
在Java中下面关于构造方法说法错误的是()
√A) 对于每一个类,Java虚拟机都提供一个默认构造方法
// 若已创建构造方法,则不提供默认构造方法
×B) 构造方法不能有返回类型
C) 构造方法可以接收参数
D) 当父类只有一个带参数的构造方法时,子类必须提供自定义的构造方法
下列关于构造方法的叙述中,错误的是( )
A.Java语言规定构造方法名与类名必须相同
B.Java语言规定构造方法没有返回值,但不用void声明
√C.Java语言规定构造方法不可以重载 // 应使用super
×D.Java语言规定构造方法可以声明为private // 无意义
下面关于方法的说法,不正确的是( )。
(A)Java中的构造方法名必须和类名相同
×(B)方法体是对方法的实现,包括变量声明和合法语句
√©如果一个类定义了构造方法,也可以用该类的默认构造方法
// 需重新定义默认构造方法
(D)构造方法可以声明为private
请问,以下哪些修饰符可以使其修饰的变量只能对同包类或子类有效?
请选择一个正确答案:
A) public
B) private
C) √protected
D) ×无访问修饰符 // 对子类无效
!向上转型对象的特点是()
×(A).不能操作子类新增的成员对象
(B).可以操作子类继承或重写的对象
( C).可以将对象的上转型对象强制转换到一个子类的对象
√(D).以上都是
// 多态: A extends B,B c = new A(),子类对象A上转型为B,引用变量c在编译阶段只能调用其编译时类型B所具有的方法,但运行时则执行它运行时类型A所具有的方法。
A派生出子类B,B派生出子类C,并且在Java源代码中有如下声明:
在Java中,对抽象方法描述正确的是:()
×A、可以有方法体 // 不可有方法体,即大括号,须在小括号后直接跟上分号
B、可以出现在非抽象类中
√C、是没有方法体的方法
D、抽象类中的方法都是抽象方法
!在Java中,下面关于抽象类的描述正确的是()。
a)抽象类可以被实例化
×b)抽象类不能被实例化,因为抽象类没有构造方法
//抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。
√C) 如果一个类中有一个方法被声明为抽象的,那么这个类必须是抽象类
d) 抽象类中的方法必须都是抽象的
在Java中,下面关于抽象类的描述正确的是()。
a抽象类既可以做父类,也可以做子类
b抽象类没有构造方法
c抽象类一定含有抽象方法
√d抽象类不一定含有抽象方法 //可以含有非抽象方法
//含有抽象方法的一定是抽象类
下面说法错误的是( )。
A.抽象类既可以做父类,也可以做子类
√B.abstract和final能同时修饰一个类 //final类不可继承,无意义
×C.抽象类中可以没有抽象方法,有抽象方法的类一定是抽象类或接口 //正确
D.声明为final类型的方法不能在其子类中重新定义
请问,以下哪些是抽象方法的正确形式?
请选择一个正确答案:
A. √abstract void Example()
B. ×abstract void Example(){} //抽象方法不能有方法体,不能有大括号
C. static abstract void Example()
D. final abstract void Example()
E. 方法不能定义为抽象的,只有变量可以是抽象的。
给定Java 代码如下,编译运行后,输出结果是)(选择一项)。
public class test {
static int i;
public int aMethod() {
i++;
return i;
}
public static void main(String args[]) {
Test test = new Test();
test.aMethod(); //静态变量,执行了一次
System.out.println(test.aMethod());
}
}
0 ×b) 1 √c) 2 d) 3
class ClassDemo {
public static int sum = 1;
public ClassDemo() {
sum = sum + 5;
}
}
public class ClassDemoTest {
public static void main(String args[]) {
ClassDemo demo1 = new ClassDemo();
ClassDemo demo2 = new ClassDemo();
System.out.println(demo1.sum);
}
}
A. 0 ×B. 6 √C. 11 D. 2
!在Java接口中,下列选项里有效的方法声明是( )。
a) public abstract aMethod( ) ; //没有返回类型,构造方法不能为抽象方法
√b) public abstract void aMethod( ) ;
×c) public static void aMethod( ) ; //没有方法体
d) protected abstract void aMethod( ) ; //一般为public
!子类不能窄化接口
定义外部类时不能用到的关键字是( )。
(A)final (B)public éprivate (D)abstract
private:只能在同类中使用,而外部类的上一次不是类
以下关于内部类说法错误的是:()
√!A、内部类不可以声明为abstract //可以为abstract
B、内部类既具有类的特性,又具有成员的特性
C、内部类不能与外部类同名
D、内部类可以访问外部类的private成员变量
以下关于内部类说法错误的是:()
×A、内部类可以声明为abstract
√B、内部类只能和外部类继承同一类型,不能单独继承其他类 //可继承
C、内部类不能与外部类同名
D、内部类可以访问外部类的private成员变量
有语句String s=“hello world”; ,以下操作哪个是不合法的?( )
√A、int i=s.length; //length.() ×B、s+=3;
//安全自加,自加3的类型和自己类型相同,为string,输出hello world3
C、String ts=s.trim(); D、String t=s+”!”;
下列代码的执行结果是什么? ()
String s1 = "aaa";
s1.concat("bbb");
System.out.println(s1);
√A. The string “aaa”;
×B. The string “aaabbb”; //须用s1=s1.concat(“bbb”);
C. The string “bbbaaa”;
D. The string “bbb”;
Java语言中,String str=“123456789”,System.out.println(str.indexOf(“5”)),输出结果为()。(选择一项)
a) 6
×b) 5
√c) 4 //indexOf返回第一次出现该字符的索引
d) -1
在Java中,如果要在字符串类型对象 s= "java"中,得到字母’v’出现的位置,可使用以下()语句
×a) s.matches(‘v’) //判断是否与正则表达式相同
×b) s.charAt(‘v’) //返回指定索引的char值
√c) s.indexOf(‘v’)
d) s.substring(‘v’)
给定如下Java代码,编译运行时,以下()语句的值是true。
String s=“hello”;
String t=“hello”;
String e=new String(“hello”) ;
char c[]={‘h’,e’,’l’,’l’,o’};
√a) s == t ;
×b) t.equals ( c) ; //false,同类型间比较,相同返回true
c) t == e;
d) t == c;
1. String s1=“abc”+”def”;
2. String s2=new String(s1);
3. if(s1= =s2)
4. System.out.println(“= = succeeded”);
5. if (s1.equals(s2))
6. System.out.println(“.equals() succeeded”);
A、行4与行6都将执行 B、行4执行,行6不执行
√C、行6执行,行4不执行//比较的是引用 C、行4、行6都不执行
class Example {
public static void main (String args[]){
if("String".replace('T','t')=="String")
//replace(A,B):将字符串中第一个A转为B
System.out.println("Equal");
else
System.out.println("Not Equal");
}
}
请选择一个正确的答案:
√(1) 打印输出Equal;
(2) 打印输出Not Equal;
(3)代码编译失败。
(4)打印输出String
class Example {
public static void main(String args[]) {
if (" String ".trim() == "String")
System.out.println("Equal");
// 仅比较堆内存,调用方法后存储在新的堆内存中
else
System.out.println("Not Equal");
}
}
请选择一个正确的答案:
×(1) 打印输出Equal;
√(2) 打印输出Not Equal;
class Example {
public static void main(String args[]) {
if ("STRING".toUpperCase() == "STRING")
System.out.println("Equal");
else
System.out.println("Not Equal");
}
}
请选择一个正确的答案:
√(1) 打印输出Equal; Java 字符串在栈内存和堆内存中的比较、存储方式简介
×(2) 打印输出Not Equal;
(3)代码编译失败。
(4)运行失败
有如下代码段,请问下面选项结果为false的是:
String s1 = “abc”;
String s2 = s1;
String s3 = new String(“abc”);
A、s1.intern()== s2
B、s1.intern() == s2.intern()
C、√s1.intern() == s3
D、s2.intern() == s3.intern()
!调用intern方法时,如果常量池已包含等于String方法确定的String对象的字符串,则返回常量池中的该字符串引用。 否则,将此String对象添加到池中,并返回对此String对象的引用。
详情见:Java intern() 方法 | 菜鸟教程
在异常处理中,如释放资源、关闭文件、关闭数据库等由( )来完成。
×A.try子句 B.catch子句
!√C.finally子句 D.throw子句
下列描述了Java语言通过面向对象的方法进行异常处理的好处,请选出不在这些好处范围之内的一项()
A. 把各种不同的异常事件进行分类,体现了良好的继承性
B.把错误处理代码从常规代码中分离出来
√C.可以利用异常处理机制代替传统的控制流程 //不要替代传统流程
×D.可以处理意想不到的异常
下列代码中给出正确的在方法体内抛出异常的是( )。
A.new throw Exception(" “);√B.throw new Exception(” ");
C.throws IOException(); ×D.throws IOException;
throws用于声明将会抛出异常
对于catch子句的排列,下列哪种是正确的( )
A.父类在先,子类在后
√B.子类在先,父类在后
×C.有继承关系的异常不能在同一个try程序段内 //可以,须遵从B选项
D.如何排列都可以
运行以下程序段将输出什么? ()
class E {
public static void main(String args[]) {
try {
throw new ArrayIndexOutOfBoundsException();
System.out.println("condition 1");// (该句无法被执行)
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("condition 2");
} finally {
System.out.println("finally");
}
}
}
√A.编译错误
×B.condition 1
condition 2
finally
C.condition 2
D.condition 2
finally
class Example {
public static void main(String args[]) {
System.out.println(3 / 0);
}
}
请选择一个正确答案:
能读入字节数据进行Java基本数据类型判断过滤的类是( )。
×A.BufferedInputStream B.FileInputStream
√C.DataInputStream D.FileReader
在通常情况下,下列哪个类的对象可以作为BufferedReader类构造方法的参数( )?
A.PrintStream(字节输出流) B.FileInputStream (字节输入流)
C.InputStreamReader(字符输入流、转换流) D.FileWriter (字符输出流)
Java系统标准输入对象System.in使用的输入流是( )。
A.PrintStream √B.InputStream
C.InputStreamReader ×D.DataIutputStream
在读字符文件Employee.dat时,使用该文件作为参数的类是()
A.BufferReader
×B.DataInputStream
C.DataOutputStream
√D.FileInputStream
下列关于流类和File类的说法中错误的一项是( )。
A.File类可以重命名文件 √B.File类可以修改文件内容
C.流类可以修改文件内容 ×D.流类不可以新建目录
!File能新建、删除、重命名文件和目录,但不能访问文件本身。如要访问需使用输入输出流。
!下列哪个方法可以将JMenuBar加入JFrame中( )?
A.setJMenu() B.addJMenuBar()
×C.add() √D.setJMenuBar()
Container是下列哪一个类的子类( )?
A.Graphics B.Window C.Applet √D.Component
如下哪个方法可以从 WindowEvent 获取事件源 ?
A 、 getFrame()
B 、 getID()
√C 、 getSource()
D 、 getEvent()
当单击鼠标或拖动鼠标时,触发的事件是( )。
A.KeyEvent ×B.ActionEvent C.ItemEvent √D.MouseEvent
对于Java中的布局管理器,以下说法中错误的是()。(选择一项)
a) FlowLayout 以由上到下的方式从左到右排列组件
b) BorderLayout 使用”东”、”西”、”南”、”北”,”居中”来指定组件的位置
√c) GridLayout 可以创建网格布局,网格布局中各组件的大小可以任意调整
// 大小由组件所处区域来决定(每个组件自动占满整个区域)
d )可以通过容器的setLayout 方法为容器指定布局管理器
在Java中,与数据库连接的技术是 ()
A.ODBC
√B.JDBC //Java Database Connectivity
C.数据库厂家驱动程序
D.数据库厂家的连接协议
下面的哪一个关键字通常用来对对象加锁,从而使得对对象的访问是排他的( )?
A.serialize B.transient
!√C.synchronized D.static
Thread类定义在下列哪个包中( )?
A.java.io !√B.java.lang
C.java.util D.java.awt
下列关于Thread类的线程控制方法的说法中错误的一项是( )。
A.线程可以通过调用sleep()方法使比当前线程优先级低的线程运行
B.线程可以通过调用yield()方法使和当前线程优先级一样的线程运行
√C.线程的yield()方法调用结束后,该线程进入运行状态(进入就绪状态)
×D.若没有相同优先级的线程处于可运行状态,线程调用yield()方法时,当前线程将继续执行 //正确
各种库里面都有对应的方法吧
一、插件概述
Windows资源管理器是Windows操作系统中常用的文件管理工具,它能够让用户方便地管理本地硬盘、光驱、网络驱动器等文件资源。本文将介绍如何为Windows资源管理器编写一个插件,实现过滤捕获双击文件和文件夹、关闭文件夹的操作。
二、插件开发
1.开发环境
本插件使用C/C++语言进行开发,开发环境为Visual Studio 2019。
2.创建插件工程
首先打开Visual Studio,选择“新建项目”,在弹出的对话框中选择“Win32控制台应用程序”,填写项目名称和路径后点击“创建”按钮。在弹出的向导中,勾选“DLL”(动态链接库)选项,保持默认设置并点击“完成”按钮创建工程。
3.添加头文件和库文件
为了使用Windows API函数,我们需要添加头文件和库文件。我们需要使用以下头文件:
#include <Windows.h> // Windows API 基础头文件
#include <ShlObj.h> // Shell API 头文件
需要用到的库文件有:
Shell32.lib // Shell API 库文件
可以在项目属性中添加上述库文件路径,或直接使用#pragma comment方式在代码中引用。
4.实现DLL导出函数
编写插件需要导出的函数,供Windows资源管理器调用。
我们需要导出以下两个函数:
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpReserved);
BOOL WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
其中,DllMain函数是DLL的入口函数,我们可以在其中做一些初始化操作。DllGetClassObject函数用于获取对象指针,这里我们不需要实现该函数。
5.实现捕获双击文件和文件夹的操作
要实现捕获双击文件和文件夹的操作,我们需要实现ShellExecute函数的钩子函数。ShellExecute是Windows API中的一个函数,可以启动一个应用程序或者打开一个文件。
我们需要使用以下函数进行钩子:
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
LRESULT CallNextHookEx(HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam);
BOOL UnhookWindowsHookEx(HHOOK hhk);
我们将钩子设置为WH_CALLWNDPROCRET,意思是我们会在ShellExecute函数被调用之后,返回结果之前进行一些操作。
代码如下:
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* pMsg = (CWPSTRUCT*)lParam;
if (pMsg->message == WM_DESTROY)
{
HWND hFolderWnd = (HWND)pMsg->wParam;
PostMessage(hFolderWnd, WM_CLOSE, 0, 0);
}
if (pMsg->message == WM_COMMAND)
{
UINT nID = LOWORD(pMsg->wParam);
if (nID == 0xE122)
{
LPCTSTR lpszFilePath = (LPCTSTR)pMsg->lParam;
if (lpszFilePath == NULL || lstrlen(lpszFilePath) == 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
// 判断是否是文件夹
DWORD dwAttr = GetFileAttributes(lpszFilePath);
if (dwAttr == INVALID_FILE_ATTRIBUTES)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
{
// 如果是文件夹,取消操作
return TRUE;
}
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
在这里,我们判断pMsg->message的值,如果是WM_COMMAND,并且nID等于0xE122,那么表示这是ShellExecute函数被调用。此时,我们获取到了待打开的文件路径,判断该路径是否是文件夹,如果是,则取消操作,如果不是,则继续执行。
6.实现关闭文件夹的操作
要实现关闭文件夹的操作,我们需要在前面的代码中添加一些内容。
当我们双击一个文件夹时,Windows资源管理器会打开该文件夹并显示其中的内容。如果我们希望关闭该文件夹,我们可以向该文件夹所对应的窗口发送一个WM_CLOSE消息,这样就可以使该文件夹窗口关闭。
代码如下:
if (pMsg->message == WM_DESTROY)
{
HWND hFolderWnd = (HWND)pMsg->wParam;
PostMessage(hFolderWnd, WM_CLOSE, 0, 0);
}
在这里,我们判断pMsg->message的值,如果是WM_DESTROY,那么表示该窗口即将被销毁,此时我们获取到窗口句柄,并向该窗口发送一个WM_CLOSE消息,从而实现关闭文件夹的操作。
7.编译和部署
完成代码编写后,我们需要进行编译。编译完成后,我们将得到一个DLL文件。此时,我们需要将该DLL文件放到Windows资源管理器的插件目录下,例如C:\Windows\System32\或C:\Windows\SysWOW64(如果是64位系统)目录中。
最后,我们需要重启Windows资源管理器才能使插件生效。
三、插件使用
完成插件的开发和部署后,我们就可以使用该插件了。
现在,当我们在Windows资源管理器中双击一个文件或者文件夹时,如果该文件或者文件夹是一个文件夹,那么就会被关闭;如果不是一个文件夹,那么就会继续执行默认操作(例如打开文件)。
总结
本文简单介绍了如何为Windows资源管理器编写一个插件,实现过滤捕获双击文件和文件夹、关闭文件夹的操作。我们可以通过钩子函数来截获ShellExecute函数的调用,从而实现取消操作或者关闭文件夹。通过本文的示例,希望读者可以了解到如何使用Windows API函数来实现Windows资源管理器的插件开发。
用java 操作word 使其变成图片和文字对齐 的实现
package com.util;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import com.aspose.words.Document;
import com.aspose.words.ImageSaveOptions;
import com.aspose.words.SaveFormat;
public class OfficeUtils {
/**
* 验证aspose.word组件是否授权:无授权的文件有水印标记
* 需要使用(aspose-words-15.8.0-jdk16.jar),版本要对应。无水印
* @return
*/
public static boolean isWordLicense()
{
boolean result = false;
try {
String s = "<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature></License>";
ByteArrayInputStream inputStream = new ByteArrayInputStream(s.getBytes());
com.aspose.words.License license = new com.aspose.words.License();
license.setLicense(inputStream);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
//outputStream转inputStream
public static ByteArrayInputStream parse(OutputStream out) throws Exception
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos = (ByteArrayOutputStream) out;
ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
return swapStream;
}
/**
* word和txt文件转换图片
* @param inputStream
* @param
* @return
* @throws Exception
*/
private static List<BufferedImage> wordToImg(InputStream inputStream) throws Exception
{
if (!isWordLicense())
{
return null;
}
try {
Date start = new Date();
Document doc = new Document(inputStream);
ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG);
options.setPrettyFormat(true);
options.setUseAntiAliasing(true);
options.setUseHighQualityRendering(true);
int pageCount = doc.getPageCount();
//生成前pageCount张,这可以限制输出长图时的页数(方法入参可以传值pageNum)
/*if (pageCount > pageNum) {
pageCount = pageNum;
}*/
List<BufferedImage> imageList = new ArrayList<BufferedImage>();
for (int i = 0; i < pageCount; i++)
{
OutputStream output = new ByteArrayOutputStream();
options.setPageIndex(i);
doc.save(output, options);
ImageInputStream imageInputStream = javax.imageio.ImageIO.createImageInputStream(parse(output));
imageList.add(javax.imageio.ImageIO.read(imageInputStream));
}
List<BufferedImage> imageList2 = new ArrayList<BufferedImage>();
//这个重新生成新的图片是因为直接输出的图片底色为红色
for(int j=0; j<imageList.size(); j++)
{
// 生成新图片
BufferedImage destImage = imageList.get(j);
int w1 = destImage.getWidth();
int h1 = destImage.getHeight();
destImage = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) destImage.getGraphics();
g2.setBackground(Color.LIGHT_GRAY);
g2.clearRect(0, 0, w1, h1);
g2.setPaint(Color.RED);
// 从图片中读取RGB
int[] ImageArrayOne = new int[w1 * h1];
ImageArrayOne = imageList.get(j).getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
destImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
imageList2.add(destImage);
}
Date end = new Date();
long l=end.getTime()-start.getTime();
long hour= l / (1000 * 60 * 60);
long min= (l-hour*(1000 * 60 * 60 ))/(1000* 60);
long s= (l-hour*(1000 * 60 * 60 )-min*1000*60)/(1000);
long ss= (l-hour*(1000 * 60 * 60 )-min*1000*60 -s*1000)/(1000/60);
System.out.println("word转图片时间:"+min+"分"+s+"秒" + ss + "毫秒");//hour+"小时"+
return imageList2;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
/**
* 合并任数量的图片成一张图片
* @param isHorizontal true代表水平合并,fasle代表垂直合并
* @param imgs 待合并的图片数组
* @return
* @throws IOException
*/
public static BufferedImage mergeImage(boolean isHorizontal, List<BufferedImage> imgs) throws IOException
{
// 生成新图片
BufferedImage destImage = null;
// 计算新图片的长和高
int allw = 0, allh = 0, allwMax = 0, allhMax = 0;
// 获取总长、总宽、最长、最宽
for (int i = 0; i < imgs.size(); i++)
{
BufferedImage img = imgs.get(i);
allw += img.getWidth();
if (imgs.size() != i + 1)
{
allh += img.getHeight() + 5;
} else {
allh += img.getHeight();
}
if (img.getWidth() > allwMax)
{
allwMax = img.getWidth();
}
if (img.getHeight() > allhMax)
{
allhMax = img.getHeight();
}
}
// 创建新图片
if (isHorizontal)
{
destImage = new BufferedImage(allw, allhMax, BufferedImage.TYPE_INT_RGB);
} else {
destImage = new BufferedImage(allwMax, allh, BufferedImage.TYPE_INT_RGB);
}
Graphics2D g2 = (Graphics2D) destImage.getGraphics();
g2.setBackground(Color.LIGHT_GRAY);
g2.clearRect(0, 0, allw, allh);
g2.setPaint(Color.RED);
// 合并所有子图片到新图片
int wx = 0, wy = 0;
for (int i = 0; i < imgs.size(); i++)
{
BufferedImage img = imgs.get(i);
int w1 = img.getWidth();
int h1 = img.getHeight();
// 从图片中读取RGB
int[] ImageArrayOne = new int[w1 * h1];
ImageArrayOne = img.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
if (isHorizontal) { // 水平方向合并
destImage.setRGB(wx, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
} else { // 垂直方向合并
destImage.setRGB(0, wy, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
}
wx += w1;
wy += h1 + 5;
}
return destImage;
}
// 测试工具类
public static void main(String[] args)
{
//word转图片格式
try {
File file = new File("G:\\test\\test22.docx");
InputStream inStream = new FileInputStream(file);
List<BufferedImage> wordToImg = wordToImg(inStream);
//for(int i=0; i<wordToImg.size(); i++){ //可以保存图片(每页保存为一张)
// ImageIO.write(wordToImg.get(i), "jpg", new File("G:\\test\\"+ i +".png")); //将其保存在C:/imageSort/targetPIC/下
//}
BufferedImage mergeImage = mergeImage(false, wordToImg);
//保存图片(长图)
ImageIO.write(mergeImage, "jpg", new File("G:\\test\\test.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
要使用Java操作Word文档,你会需要Apache POI这样的库。以下是一个简单的示例,演示如何在页脚添加图片并使其与文本对齐:
import org.apache.poi.xwpf.usermodel.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
public class WordFooterImageText {
public static void main(String[] args) throws Exception {
XWPFDocument doc = new XWPFDocument();
XWPFParagraph title = doc.createParagraph();
XWPFRun run = title.createRun();
run.setText("这是一个示例文档。");
// 创建页脚
XWPFFooter footer = doc.createFooter(HeaderFooterType.DEFAULT);
final XWPFParagraph paragraph = footer.createParagraph();
final XWPFRun footerRun = paragraph.createRun();
// 添加文本
footerRun.addTab(); // 添加一个制表符以空出一些空间
footerRun.setText("页脚文本");
// 添加图片
final String imgFile = "路径/图片.jpg";
try(InputStream is = new FileInputStream(imgFile)){
//将图片转换为byte数组
BufferedImage bImage = ImageIO.read(is);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(bImage, "jpg", bos );
byte [] bytes = bos.toByteArray();
//添加图片
footerRun.addPicture(new ByteArrayInputStream(bytes), XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(200), Units.toEMU(200));
}
try(OutputStream os = new FileOutputStream("Test_Document.docx")){
doc.write(os);
}
System.out.println("创建完成");
}
}
这个示例首先创建了一个新的Word文档并在其主体部分添加了一些文字。然后在页脚添加了一个新的段落,并在该段落添加了一些文字。
接着,它读入了一个JPEG格式的图片,将它转换为byte数组,并添加到页脚段落。最后,它将这个Word文档保存到文件"Test_Document.docx"中。
请注意,这只是一个很基本的示例。你可能需要对这个代码进行修改以达到你的特定需求,比如调整图片的大小或者位置,修改文本的样式等等。