本博客 jacob 列文章導(dǎo)讀
Java操作Microsoft Word之jacob
jacob使用入門及問題解析
使用Jacob將Word轉(zhuǎn)為Html或txt
使用Jacob將Word轉(zhuǎn)為PDF
java通過jacob調(diào)用word (根據(jù)Word模板生成動態(tài)內(nèi)容)
現(xiàn)在我們一起來看看,用Java如何操作Microsoft Word。
jacob,官網(wǎng)是
http://danadler.com/jacob
這是一個開源的工具。
最新版本1.9
官方的解釋是:
The JACOB Project: A JAva-COM Bridge
這是官方對下載文件的說明:
- jacob.jar: a JAR file for the java classes which you must add to your CLASSPATH. The package names replace com.ms with com.jacob (for example com.ms.com.Variant maps to com.jacob.com.Variant.
- jacob.dll: a small Win32 DLL which you must add to your PATH.
- samples: provided in Java source and compiled form to demonstrate various features of the product. In particular, a set of wrapper classes for Microsoft? ADO are provided as samples.
開發(fā)環(huán)境:
JDK 1.6
MyEclipse Enterprise Workbench Version: 7.0 Milestone-1
Tomcat 5.5.27
現(xiàn)在MyEclipse中新建一個項目jacob,將jacob的jar包放到該項目的類庫中。
我的jacob版本是1.14.3 。
下面這一步非常重要,就是拷貝jacob目錄中jacob-1.14.3-x86.dll文件到系統(tǒng)環(huán)境變量目錄中
一般情況就放在當(dāng)前jdk中bin目錄下。
這里有一個MSWordManager 類,是jacob官方發(fā)布的工具類,里面有大多數(shù)Java操作MS Office的工具。
package
com.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class MSWordManager {
// word文檔
private Dispatch doc;
// word運行程序?qū)ο?
private ActiveXComponent word;
// 所有word文檔集合
private Dispatch documents;
// 選定的范圍或插入點
private Dispatch selection;
private boolean saveOnExit = true ;
/** *//**
*
* @param visible 為true表示word應(yīng)用程序可見
*/
public MSWordManager( boolean visible) {
if (word == null ) {
word = new ActiveXComponent( "Word.Application" );
word.setProperty( "Visible" , new Variant(visible));
}
if (documents == null )
documents = word.getProperty( "Documents" ).toDispatch();
}
/** *//**
* 設(shè)置退出時參數(shù)
*
* @param saveOnExit boolean true-退出時保存文件,false-退出時不保存文件
*/
public void setSaveOnExit( boolean saveOnExit) {
this .saveOnExit = saveOnExit;
}
/** *//**
* 創(chuàng)建一個新的word文檔
*
*/
public void createNewDocument() {
doc = Dispatch.call(documents, "Add" ).toDispatch();
selection = Dispatch.get(word, "Selection" ).toDispatch();
}
/** *//**
* 打開一個已存在的文檔
*
* @param docPath
*/
public void openDocument(String docPath) {
closeDocument();
doc = Dispatch.call(documents, "Open" , docPath).toDispatch();
selection = Dispatch.get(word, "Selection" ).toDispatch();
}
/** *//**
* 把選定的內(nèi)容或插入點向上移動
*
* @param pos 移動的距離
*/
public void moveUp( int pos) {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
for ( int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveUp" );
}
/** *//**
* 把選定的內(nèi)容或者插入點向下移動
*
* @param pos 移動的距離
*/
public void moveDown( int pos) {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
for ( int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveDown" );
}
/** *//**
* 把選定的內(nèi)容或者插入點向左移動
*
* @param pos 移動的距離
*/
public void moveLeft( int pos) {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
for ( int i = 0; i < pos; i++) {
Dispatch.call(selection, "MoveLeft" );
}
}
/** *//**
* 把選定的內(nèi)容或者插入點向右移動
*
* @param pos 移動的距離
*/
public void moveRight( int pos) {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
for ( int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveRight" );
}
/** *//**
* 把插入點移動到文件首位置
*
*/
public void moveStart() {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
Dispatch.call(selection, "HomeKey" , new Variant(6));
}
public void moveEnd() {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
Dispatch.call(selection, "EndKey" , new Variant(6));
}
/** *//**
* 從選定內(nèi)容或插入點開始查找文本
*
* @param toFindText 要查找的文本
* @return boolean true-查找到并選中該文本,false-未查找到文本
*/
public boolean find(String toFindText) {
if (toFindText == null || toFindText.equals(""))
return false ;
// 從selection所在位置開始查詢
Dispatch find = word.call(selection, "Find" ).toDispatch();
// 設(shè)置要查找的內(nèi)容
Dispatch.put(find, "Text" , toFindText);
// 向前查找
Dispatch.put(find, "Forward" , "True" );
// 設(shè)置格式
Dispatch.put(find, "Format" , "True" );
// 大小寫匹配
Dispatch.put(find, "MatchCase" , "True" );
// 全字匹配
Dispatch.put(find, "MatchWholeWord" , "True" );
// 查找并選中
return Dispatch.call(find, "Execute" ).getBoolean();
}
/** *//**
* 把選定選定內(nèi)容設(shè)定為替換文本
*
* @param toFindText 查找字符串
* @param newText 要替換的內(nèi)容
* @return
*/
public boolean replaceText(String toFindText, String newText) {
if (!find(toFindText))
return false ;
Dispatch.put(selection, "Text" , newText);
return true ;
}
/** *//**
* 全局替換文本
*
* @param toFindText 查找字符串
* @param newText 要替換的內(nèi)容
*/
public void replaceAllText(String toFindText, String newText) {
while (find(toFindText)) {
Dispatch.put(selection, "Text" , newText);
Dispatch.call(selection, "MoveRight" );
}
}
/** *//**
* 在當(dāng)前插入點插入字符串
*
* @param newText 要插入的新字符串
*/
public void insertText(String newText) {
Dispatch.put(selection, "Text" , newText);
}
/** *//**
*
* @param toFindText 要查找的字符串
* @param imagePath 圖片路徑
* @return
*/
public boolean replaceImage(String toFindText, String imagePath) {
if (!find(toFindText))
return false ;
Dispatch.call(Dispatch.get(selection, "InLineShapes" ).toDispatch(),
"AddPicture" , imagePath);
return true ;
}
/** *//**
* 全局替換圖片
*
* @param toFindText 查找字符串
* @param imagePath 圖片路徑
*/
public void replaceAllImage(String toFindText, String imagePath) {
while (find(toFindText)) {
Dispatch.call(Dispatch.get(selection, "InLineShapes" ).toDispatch(),
"AddPicture" , imagePath);
Dispatch.call(selection, "MoveRight" );
}
}
/** *//**
* 在當(dāng)前插入點插入圖片
*
* @param imagePath 圖片路徑
*/
public void insertImage(String imagePath) {
Dispatch.call(Dispatch.get(selection, "InLineShapes" ).toDispatch(),
"AddPicture" , imagePath);
}
/** *//**
* 合并單元格
*
* @param tableIndex
* @param fstCellRowIdx
* @param fstCellColIdx
* @param secCellRowIdx
* @param secCellColIdx
*/
public void mergeCell( int tableIndex, int fstCellRowIdx, int fstCellColIdx,
int secCellRowIdx, int secCellColIdx) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
Dispatch fstCell = Dispatch.call(table, "Cell" ,
new Variant(fstCellRowIdx), new Variant(fstCellColIdx))
.toDispatch();
Dispatch secCell = Dispatch.call(table, "Cell" ,
new Variant(secCellRowIdx), new Variant(secCellColIdx))
.toDispatch();
Dispatch.call(fstCell, "Merge" , secCell);
}
/** *//**
* 在指定的單元格里填寫數(shù)據(jù)
*
* @param tableIndex
* @param cellRowIdx
* @param cellColIdx
* @param txt
*/
public void putTxtToCell( int tableIndex, int cellRowIdx, int cellColIdx,
String txt) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
Dispatch cell = Dispatch.call(table, "Cell" , new Variant(cellRowIdx),
new Variant(cellColIdx)).toDispatch();
Dispatch.call(cell, "Select" );
Dispatch.put(selection, "Text" , txt);
}
/** *//**
* 在當(dāng)前文檔拷貝數(shù)據(jù)
*
* @param pos
*/
public void copy(String toCopyText) {
moveStart();
if ( this .find(toCopyText)) {
Dispatch textRange = Dispatch.get(selection, "Range" ).toDispatch();
Dispatch.call(textRange, "Copy" );
}
}
/** *//**
* 在當(dāng)前文檔粘帖剪貼板數(shù)據(jù)
*
* @param pos
*/
public void paste(String pos) {
moveStart();
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" ).toDispatch();
Dispatch.call(textRange, "Paste" );
}
}
/** *//**
* 在當(dāng)前文檔指定的位置拷貝表格
*
* @param pos 當(dāng)前文檔指定的位置
* @param tableIndex 被拷貝的表格在word文檔中所處的位置
*/
public void copyTable(String pos, int tableIndex) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
Dispatch range = Dispatch.get(table, "Range" ).toDispatch();
Dispatch.call(range, "Copy" );
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" ).toDispatch();
Dispatch.call(textRange, "Paste" );
}
}
/** *//**
* 在當(dāng)前文檔末尾拷貝來自另一個文檔中的段落
*
* @param anotherDocPath 另一個文檔的磁盤路徑
* @param tableIndex 被拷貝的段落在另一格文檔中的序號(從1開始)
*/
public void copyParagraphFromAnotherDoc(String anotherDocPath,
int paragraphIndex) {
Dispatch wordContent = Dispatch.get(doc, "Content" ).toDispatch(); // 取得當(dāng)前文檔的內(nèi)容
Dispatch.call(wordContent, "InsertAfter" , "$selection$" ); // 插入特殊符定位插入點
copyParagraphFromAnotherDoc(anotherDocPath, paragraphIndex,
"$selection$" );
}
/** *//**
* 在當(dāng)前文檔指定的位置拷貝來自另一個文檔中的段落
*
* @param anotherDocPath 另一個文檔的磁盤路徑
* @param tableIndex 被拷貝的段落在另一格文檔中的序號(從1開始)
* @param pos 當(dāng)前文檔指定的位置
*/
public void copyParagraphFromAnotherDoc(String anotherDocPath,
int paragraphIndex, String pos) {
Dispatch doc2 = null ;
try {
doc2 = Dispatch.call(documents, "Open" , anotherDocPath)
.toDispatch();
Dispatch paragraphs = Dispatch.get(doc2, "Paragraphs" ).toDispatch();
Dispatch paragraph = Dispatch.call(paragraphs, "Item" ,
new Variant(paragraphIndex)).toDispatch();
Dispatch range = Dispatch.get(paragraph, "Range" ).toDispatch();
Dispatch.call(range, "Copy" );
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" )
.toDispatch();
Dispatch.call(textRange, "Paste" );
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (doc2 != null ) {
Dispatch.call(doc2, "Close" , new Variant(saveOnExit));
doc2 = null ;
}
}
}
/** *//**
* 在當(dāng)前文檔指定的位置拷貝來自另一個文檔中的表格
*
* @param anotherDocPath 另一個文檔的磁盤路徑
* @param tableIndex 被拷貝的表格在另一格文檔中的序號(從1開始)
* @param pos 當(dāng)前文檔指定的位置
*/
public void copyTableFromAnotherDoc(String anotherDocPath, int tableIndex,
String pos) {
Dispatch doc2 = null ;
try {
doc2 = Dispatch.call(documents, "Open" , anotherDocPath)
.toDispatch();
Dispatch tables = Dispatch.get(doc2, "Tables" ).toDispatch();
Dispatch table = Dispatch.call(tables, "Item" ,
new Variant(tableIndex)).toDispatch();
Dispatch range = Dispatch.get(table, "Range" ).toDispatch();
Dispatch.call(range, "Copy" );
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" )
.toDispatch();
Dispatch.call(textRange, "Paste" );
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (doc2 != null ) {
Dispatch.call(doc2, "Close" , new Variant(saveOnExit));
doc2 = null ;
}
}
}
/** *//**
* 在當(dāng)前文檔指定的位置拷貝來自另一個文檔中的圖片
*
* @param anotherDocPath 另一個文檔的磁盤路徑
* @param shapeIndex 被拷貝的圖片在另一格文檔中的位置
* @param pos 當(dāng)前文檔指定的位置
*/
public void copyImageFromAnotherDoc(String anotherDocPath, int shapeIndex,
String pos) {
Dispatch doc2 = null ;
try {
doc2 = Dispatch.call(documents, "Open" , anotherDocPath)
.toDispatch();
Dispatch shapes = Dispatch.get(doc2, "InLineShapes" ).toDispatch();
Dispatch shape = Dispatch.call(shapes, "Item" ,
new Variant(shapeIndex)).toDispatch();
Dispatch imageRange = Dispatch.get(shape, "Range" ).toDispatch();
Dispatch.call(imageRange, "Copy" );
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" )
.toDispatch();
Dispatch.call(textRange, "Paste" );
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (doc2 != null ) {
Dispatch.call(doc2, "Close" , new Variant(saveOnExit));
doc2 = null ;
}
}
}
/** *//**
* 創(chuàng)建表格
*
* @param pos 位置
* @param cols 列數(shù)
* @param rows 行數(shù)
*/
public void createTable( int numCols, int numRows){ //(String pos, int numCols, int numRows) {
// if (!find(pos)) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
Dispatch range = Dispatch.get(selection, "Range" ).toDispatch();
Dispatch newTable = Dispatch.call(tables, "Add" , range,
new Variant(numRows), new Variant(numCols)).toDispatch();
Dispatch.call(selection, "MoveRight" );
moveEnd();
// }
}
/** *//**
* 在指定行前面增加行
*
* @param tableIndex word文件中的第N張表(從1開始)
* @param rowIndex 指定行的序號(從1開始)
*/
public void addTableRow( int tableIndex, int rowIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch rows = Dispatch.get(table, "Rows" ).toDispatch();
Dispatch row = Dispatch.call(rows, "Item" , new Variant(rowIndex))
.toDispatch();
Dispatch.call(rows, "Add" , new Variant(row));
}
/** *//**
* 在第1行前增加一行
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addFirstTableRow( int tableIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch rows = Dispatch.get(table, "Rows" ).toDispatch();
Dispatch row = Dispatch.get(rows, "First" ).toDispatch();
Dispatch.call(rows, "Add" , new Variant(row));
}
/** *//**
* 在最后1行前增加一行
*
* @param tableIndex
* word文檔中的第N張表(從1開始)
*/
public void addLastTableRow( int tableIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch rows = Dispatch.get(table, "Rows" ).toDispatch();
Dispatch row = Dispatch.get(rows, "Last" ).toDispatch();
Dispatch.call(rows, "Add" , new Variant(row));
}
/** *//**
* 增加一行
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addRow( int tableIndex) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch rows = Dispatch.get(table, "Rows" ).toDispatch();
Dispatch.call(rows, "Add" );
}
/** *//**
* 增加一列
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addCol( int tableIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
Dispatch.call(cols, "Add" ).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
/** *//**
* 在指定列前面增加表格的列
*
* @param tableIndex word文檔中的第N張表(從1開始)
* @param colIndex 指定列的序號 (從1開始)
*/
public void addTableCol( int tableIndex, int colIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
System.out.println(Dispatch.get(cols, "Count" ));
Dispatch col = Dispatch.call(cols, "Item" , new Variant(colIndex))
.toDispatch();
// Dispatch col = Dispatch.get(cols, "First").toDispatch();
Dispatch.call(cols, "Add" , col).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
/** *//**
* 在第1列前增加一列
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addFirstTableCol( int tableIndex) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
Dispatch col = Dispatch.get(cols, "First" ).toDispatch();
Dispatch.call(cols, "Add" , col).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
/** *//**
* 在最后一列前增加一列
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addLastTableCol( int tableIndex) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
Dispatch col = Dispatch.get(cols, "Last" ).toDispatch();
Dispatch.call(cols, "Add" , col).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
/** *//**
* 自動調(diào)整表格
*
*/
public void autoFitTable() {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
int count = Dispatch.get(tables, "Count" ).toInt();
for ( int i = 0; i < count; i++) {
Dispatch table = Dispatch.call(tables, "Item" , new Variant(i + 1))
.toDispatch();
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
}
/** *//**
* 調(diào)用word里的宏以調(diào)整表格的寬度,其中宏保存在document下
*
*/
public void callWordMacro() {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
int count = Dispatch.get(tables, "Count" ).toInt();
Variant vMacroName = new Variant( "Normal.NewMacros.tableFit" );
Variant vParam = new Variant( "param1" );
Variant para[] = new Variant[] { vMacroName };
for ( int i = 0; i < para.length; i++) {
Dispatch table = Dispatch.call(tables, "Item" , new Variant(i + 1))
.toDispatch();
Dispatch.call(table, "Select" );
Dispatch.call(word, "Run" , "tableFitContent" );
}
}
/** *//**
* 設(shè)置當(dāng)前選定內(nèi)容的字體
*
* @param boldSize
* @param italicSize
* @param underLineSize 下劃線
* @param colorSize 字體顏色
* @param size 字體大小
* @param name 字體名稱
*/
public void setFont( boolean bold, boolean italic, boolean underLine,
String colorSize, String size, String name) {
Dispatch font = Dispatch.get(selection, "Font" ).toDispatch();
Dispatch.put(font, "Name" , new Variant(name));
Dispatch.put(font, "Bold" , new Variant(bold));
Dispatch.put(font, "Italic" , new Variant(italic));
Dispatch.put(font, "Underline" , new Variant(underLine));
Dispatch.put(font, "Color" , colorSize);
Dispatch.put(font, "Size" , size);
}
/** *//**
* 文件保存或另存為
*
* @param savePath 保存或另存為路徑
*/
public void save(String savePath) {
Dispatch.call(
(Dispatch) Dispatch.call(word, "WordBasic" ).getDispatch(),
"FileSaveAs" , savePath);
}
/** *//**
* 關(guān)閉當(dāng)前word文檔
*
*/
public void closeDocument() {
if (doc != null ) {
Dispatch.call(doc, "Save" );
Dispatch.call(doc, "Close" , new Variant(saveOnExit));
doc = null ;
}
}
/** *//**
* 關(guān)閉全部應(yīng)用
*
*/
public void close() {
closeDocument();
if (word != null ) {
Dispatch.call(word, "Quit" );
word = null ;
}
selection = null ;
documents = null ;
}
/** *//**
* 打印當(dāng)前word文檔
*
*/
public void printFile() {
if (doc != null ) {
Dispatch.call(doc, "PrintOut" );
}
}
public static void main(String args[]) throws Exception {
MSWordManager msWordManager = new MSWordManager( true );
msWordManager.createNewDocument();
msWordManager.insertText( "aaaaaaaaaaaaaaaaaaaaa" );
msWordManager.moveEnd();
msWordManager.close();
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class MSWordManager {
// word文檔
private Dispatch doc;
// word運行程序?qū)ο?
private ActiveXComponent word;
// 所有word文檔集合
private Dispatch documents;
// 選定的范圍或插入點
private Dispatch selection;
private boolean saveOnExit = true ;
/** *//**
*
* @param visible 為true表示word應(yīng)用程序可見
*/
public MSWordManager( boolean visible) {
if (word == null ) {
word = new ActiveXComponent( "Word.Application" );
word.setProperty( "Visible" , new Variant(visible));
}
if (documents == null )
documents = word.getProperty( "Documents" ).toDispatch();
}
/** *//**
* 設(shè)置退出時參數(shù)
*
* @param saveOnExit boolean true-退出時保存文件,false-退出時不保存文件
*/
public void setSaveOnExit( boolean saveOnExit) {
this .saveOnExit = saveOnExit;
}
/** *//**
* 創(chuàng)建一個新的word文檔
*
*/
public void createNewDocument() {
doc = Dispatch.call(documents, "Add" ).toDispatch();
selection = Dispatch.get(word, "Selection" ).toDispatch();
}
/** *//**
* 打開一個已存在的文檔
*
* @param docPath
*/
public void openDocument(String docPath) {
closeDocument();
doc = Dispatch.call(documents, "Open" , docPath).toDispatch();
selection = Dispatch.get(word, "Selection" ).toDispatch();
}
/** *//**
* 把選定的內(nèi)容或插入點向上移動
*
* @param pos 移動的距離
*/
public void moveUp( int pos) {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
for ( int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveUp" );
}
/** *//**
* 把選定的內(nèi)容或者插入點向下移動
*
* @param pos 移動的距離
*/
public void moveDown( int pos) {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
for ( int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveDown" );
}
/** *//**
* 把選定的內(nèi)容或者插入點向左移動
*
* @param pos 移動的距離
*/
public void moveLeft( int pos) {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
for ( int i = 0; i < pos; i++) {
Dispatch.call(selection, "MoveLeft" );
}
}
/** *//**
* 把選定的內(nèi)容或者插入點向右移動
*
* @param pos 移動的距離
*/
public void moveRight( int pos) {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
for ( int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveRight" );
}
/** *//**
* 把插入點移動到文件首位置
*
*/
public void moveStart() {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
Dispatch.call(selection, "HomeKey" , new Variant(6));
}
public void moveEnd() {
if (selection == null )
selection = Dispatch.get(word, "Selection" ).toDispatch();
Dispatch.call(selection, "EndKey" , new Variant(6));
}
/** *//**
* 從選定內(nèi)容或插入點開始查找文本
*
* @param toFindText 要查找的文本
* @return boolean true-查找到并選中該文本,false-未查找到文本
*/
public boolean find(String toFindText) {
if (toFindText == null || toFindText.equals(""))
return false ;
// 從selection所在位置開始查詢
Dispatch find = word.call(selection, "Find" ).toDispatch();
// 設(shè)置要查找的內(nèi)容
Dispatch.put(find, "Text" , toFindText);
// 向前查找
Dispatch.put(find, "Forward" , "True" );
// 設(shè)置格式
Dispatch.put(find, "Format" , "True" );
// 大小寫匹配
Dispatch.put(find, "MatchCase" , "True" );
// 全字匹配
Dispatch.put(find, "MatchWholeWord" , "True" );
// 查找并選中
return Dispatch.call(find, "Execute" ).getBoolean();
}
/** *//**
* 把選定選定內(nèi)容設(shè)定為替換文本
*
* @param toFindText 查找字符串
* @param newText 要替換的內(nèi)容
* @return
*/
public boolean replaceText(String toFindText, String newText) {
if (!find(toFindText))
return false ;
Dispatch.put(selection, "Text" , newText);
return true ;
}
/** *//**
* 全局替換文本
*
* @param toFindText 查找字符串
* @param newText 要替換的內(nèi)容
*/
public void replaceAllText(String toFindText, String newText) {
while (find(toFindText)) {
Dispatch.put(selection, "Text" , newText);
Dispatch.call(selection, "MoveRight" );
}
}
/** *//**
* 在當(dāng)前插入點插入字符串
*
* @param newText 要插入的新字符串
*/
public void insertText(String newText) {
Dispatch.put(selection, "Text" , newText);
}
/** *//**
*
* @param toFindText 要查找的字符串
* @param imagePath 圖片路徑
* @return
*/
public boolean replaceImage(String toFindText, String imagePath) {
if (!find(toFindText))
return false ;
Dispatch.call(Dispatch.get(selection, "InLineShapes" ).toDispatch(),
"AddPicture" , imagePath);
return true ;
}
/** *//**
* 全局替換圖片
*
* @param toFindText 查找字符串
* @param imagePath 圖片路徑
*/
public void replaceAllImage(String toFindText, String imagePath) {
while (find(toFindText)) {
Dispatch.call(Dispatch.get(selection, "InLineShapes" ).toDispatch(),
"AddPicture" , imagePath);
Dispatch.call(selection, "MoveRight" );
}
}
/** *//**
* 在當(dāng)前插入點插入圖片
*
* @param imagePath 圖片路徑
*/
public void insertImage(String imagePath) {
Dispatch.call(Dispatch.get(selection, "InLineShapes" ).toDispatch(),
"AddPicture" , imagePath);
}
/** *//**
* 合并單元格
*
* @param tableIndex
* @param fstCellRowIdx
* @param fstCellColIdx
* @param secCellRowIdx
* @param secCellColIdx
*/
public void mergeCell( int tableIndex, int fstCellRowIdx, int fstCellColIdx,
int secCellRowIdx, int secCellColIdx) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
Dispatch fstCell = Dispatch.call(table, "Cell" ,
new Variant(fstCellRowIdx), new Variant(fstCellColIdx))
.toDispatch();
Dispatch secCell = Dispatch.call(table, "Cell" ,
new Variant(secCellRowIdx), new Variant(secCellColIdx))
.toDispatch();
Dispatch.call(fstCell, "Merge" , secCell);
}
/** *//**
* 在指定的單元格里填寫數(shù)據(jù)
*
* @param tableIndex
* @param cellRowIdx
* @param cellColIdx
* @param txt
*/
public void putTxtToCell( int tableIndex, int cellRowIdx, int cellColIdx,
String txt) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
Dispatch cell = Dispatch.call(table, "Cell" , new Variant(cellRowIdx),
new Variant(cellColIdx)).toDispatch();
Dispatch.call(cell, "Select" );
Dispatch.put(selection, "Text" , txt);
}
/** *//**
* 在當(dāng)前文檔拷貝數(shù)據(jù)
*
* @param pos
*/
public void copy(String toCopyText) {
moveStart();
if ( this .find(toCopyText)) {
Dispatch textRange = Dispatch.get(selection, "Range" ).toDispatch();
Dispatch.call(textRange, "Copy" );
}
}
/** *//**
* 在當(dāng)前文檔粘帖剪貼板數(shù)據(jù)
*
* @param pos
*/
public void paste(String pos) {
moveStart();
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" ).toDispatch();
Dispatch.call(textRange, "Paste" );
}
}
/** *//**
* 在當(dāng)前文檔指定的位置拷貝表格
*
* @param pos 當(dāng)前文檔指定的位置
* @param tableIndex 被拷貝的表格在word文檔中所處的位置
*/
public void copyTable(String pos, int tableIndex) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
Dispatch range = Dispatch.get(table, "Range" ).toDispatch();
Dispatch.call(range, "Copy" );
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" ).toDispatch();
Dispatch.call(textRange, "Paste" );
}
}
/** *//**
* 在當(dāng)前文檔末尾拷貝來自另一個文檔中的段落
*
* @param anotherDocPath 另一個文檔的磁盤路徑
* @param tableIndex 被拷貝的段落在另一格文檔中的序號(從1開始)
*/
public void copyParagraphFromAnotherDoc(String anotherDocPath,
int paragraphIndex) {
Dispatch wordContent = Dispatch.get(doc, "Content" ).toDispatch(); // 取得當(dāng)前文檔的內(nèi)容
Dispatch.call(wordContent, "InsertAfter" , "$selection$" ); // 插入特殊符定位插入點
copyParagraphFromAnotherDoc(anotherDocPath, paragraphIndex,
"$selection$" );
}
/** *//**
* 在當(dāng)前文檔指定的位置拷貝來自另一個文檔中的段落
*
* @param anotherDocPath 另一個文檔的磁盤路徑
* @param tableIndex 被拷貝的段落在另一格文檔中的序號(從1開始)
* @param pos 當(dāng)前文檔指定的位置
*/
public void copyParagraphFromAnotherDoc(String anotherDocPath,
int paragraphIndex, String pos) {
Dispatch doc2 = null ;
try {
doc2 = Dispatch.call(documents, "Open" , anotherDocPath)
.toDispatch();
Dispatch paragraphs = Dispatch.get(doc2, "Paragraphs" ).toDispatch();
Dispatch paragraph = Dispatch.call(paragraphs, "Item" ,
new Variant(paragraphIndex)).toDispatch();
Dispatch range = Dispatch.get(paragraph, "Range" ).toDispatch();
Dispatch.call(range, "Copy" );
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" )
.toDispatch();
Dispatch.call(textRange, "Paste" );
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (doc2 != null ) {
Dispatch.call(doc2, "Close" , new Variant(saveOnExit));
doc2 = null ;
}
}
}
/** *//**
* 在當(dāng)前文檔指定的位置拷貝來自另一個文檔中的表格
*
* @param anotherDocPath 另一個文檔的磁盤路徑
* @param tableIndex 被拷貝的表格在另一格文檔中的序號(從1開始)
* @param pos 當(dāng)前文檔指定的位置
*/
public void copyTableFromAnotherDoc(String anotherDocPath, int tableIndex,
String pos) {
Dispatch doc2 = null ;
try {
doc2 = Dispatch.call(documents, "Open" , anotherDocPath)
.toDispatch();
Dispatch tables = Dispatch.get(doc2, "Tables" ).toDispatch();
Dispatch table = Dispatch.call(tables, "Item" ,
new Variant(tableIndex)).toDispatch();
Dispatch range = Dispatch.get(table, "Range" ).toDispatch();
Dispatch.call(range, "Copy" );
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" )
.toDispatch();
Dispatch.call(textRange, "Paste" );
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (doc2 != null ) {
Dispatch.call(doc2, "Close" , new Variant(saveOnExit));
doc2 = null ;
}
}
}
/** *//**
* 在當(dāng)前文檔指定的位置拷貝來自另一個文檔中的圖片
*
* @param anotherDocPath 另一個文檔的磁盤路徑
* @param shapeIndex 被拷貝的圖片在另一格文檔中的位置
* @param pos 當(dāng)前文檔指定的位置
*/
public void copyImageFromAnotherDoc(String anotherDocPath, int shapeIndex,
String pos) {
Dispatch doc2 = null ;
try {
doc2 = Dispatch.call(documents, "Open" , anotherDocPath)
.toDispatch();
Dispatch shapes = Dispatch.get(doc2, "InLineShapes" ).toDispatch();
Dispatch shape = Dispatch.call(shapes, "Item" ,
new Variant(shapeIndex)).toDispatch();
Dispatch imageRange = Dispatch.get(shape, "Range" ).toDispatch();
Dispatch.call(imageRange, "Copy" );
if ( this .find(pos)) {
Dispatch textRange = Dispatch.get(selection, "Range" )
.toDispatch();
Dispatch.call(textRange, "Paste" );
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (doc2 != null ) {
Dispatch.call(doc2, "Close" , new Variant(saveOnExit));
doc2 = null ;
}
}
}
/** *//**
* 創(chuàng)建表格
*
* @param pos 位置
* @param cols 列數(shù)
* @param rows 行數(shù)
*/
public void createTable( int numCols, int numRows){ //(String pos, int numCols, int numRows) {
// if (!find(pos)) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
Dispatch range = Dispatch.get(selection, "Range" ).toDispatch();
Dispatch newTable = Dispatch.call(tables, "Add" , range,
new Variant(numRows), new Variant(numCols)).toDispatch();
Dispatch.call(selection, "MoveRight" );
moveEnd();
// }
}
/** *//**
* 在指定行前面增加行
*
* @param tableIndex word文件中的第N張表(從1開始)
* @param rowIndex 指定行的序號(從1開始)
*/
public void addTableRow( int tableIndex, int rowIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch rows = Dispatch.get(table, "Rows" ).toDispatch();
Dispatch row = Dispatch.call(rows, "Item" , new Variant(rowIndex))
.toDispatch();
Dispatch.call(rows, "Add" , new Variant(row));
}
/** *//**
* 在第1行前增加一行
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addFirstTableRow( int tableIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch rows = Dispatch.get(table, "Rows" ).toDispatch();
Dispatch row = Dispatch.get(rows, "First" ).toDispatch();
Dispatch.call(rows, "Add" , new Variant(row));
}
/** *//**
* 在最后1行前增加一行
*
* @param tableIndex
* word文檔中的第N張表(從1開始)
*/
public void addLastTableRow( int tableIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch rows = Dispatch.get(table, "Rows" ).toDispatch();
Dispatch row = Dispatch.get(rows, "Last" ).toDispatch();
Dispatch.call(rows, "Add" , new Variant(row));
}
/** *//**
* 增加一行
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addRow( int tableIndex) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch rows = Dispatch.get(table, "Rows" ).toDispatch();
Dispatch.call(rows, "Add" );
}
/** *//**
* 增加一列
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addCol( int tableIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
Dispatch.call(cols, "Add" ).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
/** *//**
* 在指定列前面增加表格的列
*
* @param tableIndex word文檔中的第N張表(從1開始)
* @param colIndex 指定列的序號 (從1開始)
*/
public void addTableCol( int tableIndex, int colIndex) {
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
System.out.println(Dispatch.get(cols, "Count" ));
Dispatch col = Dispatch.call(cols, "Item" , new Variant(colIndex))
.toDispatch();
// Dispatch col = Dispatch.get(cols, "First").toDispatch();
Dispatch.call(cols, "Add" , col).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
/** *//**
* 在第1列前增加一列
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addFirstTableCol( int tableIndex) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
Dispatch col = Dispatch.get(cols, "First" ).toDispatch();
Dispatch.call(cols, "Add" , col).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
/** *//**
* 在最后一列前增加一列
*
* @param tableIndex word文檔中的第N張表(從1開始)
*/
public void addLastTableCol( int tableIndex) {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item" , new Variant(tableIndex))
.toDispatch();
// 表格的所有行
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
Dispatch col = Dispatch.get(cols, "Last" ).toDispatch();
Dispatch.call(cols, "Add" , col).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
/** *//**
* 自動調(diào)整表格
*
*/
public void autoFitTable() {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
int count = Dispatch.get(tables, "Count" ).toInt();
for ( int i = 0; i < count; i++) {
Dispatch table = Dispatch.call(tables, "Item" , new Variant(i + 1))
.toDispatch();
Dispatch cols = Dispatch.get(table, "Columns" ).toDispatch();
Dispatch.call(cols, "AutoFit" );
}
}
/** *//**
* 調(diào)用word里的宏以調(diào)整表格的寬度,其中宏保存在document下
*
*/
public void callWordMacro() {
Dispatch tables = Dispatch.get(doc, "Tables" ).toDispatch();
int count = Dispatch.get(tables, "Count" ).toInt();
Variant vMacroName = new Variant( "Normal.NewMacros.tableFit" );
Variant vParam = new Variant( "param1" );
Variant para[] = new Variant[] { vMacroName };
for ( int i = 0; i < para.length; i++) {
Dispatch table = Dispatch.call(tables, "Item" , new Variant(i + 1))
.toDispatch();
Dispatch.call(table, "Select" );
Dispatch.call(word, "Run" , "tableFitContent" );
}
}
/** *//**
* 設(shè)置當(dāng)前選定內(nèi)容的字體
*
* @param boldSize
* @param italicSize
* @param underLineSize 下劃線
* @param colorSize 字體顏色
* @param size 字體大小
* @param name 字體名稱
*/
public void setFont( boolean bold, boolean italic, boolean underLine,
String colorSize, String size, String name) {
Dispatch font = Dispatch.get(selection, "Font" ).toDispatch();
Dispatch.put(font, "Name" , new Variant(name));
Dispatch.put(font, "Bold" , new Variant(bold));
Dispatch.put(font, "Italic" , new Variant(italic));
Dispatch.put(font, "Underline" , new Variant(underLine));
Dispatch.put(font, "Color" , colorSize);
Dispatch.put(font, "Size" , size);
}
/** *//**
* 文件保存或另存為
*
* @param savePath 保存或另存為路徑
*/
public void save(String savePath) {
Dispatch.call(
(Dispatch) Dispatch.call(word, "WordBasic" ).getDispatch(),
"FileSaveAs" , savePath);
}
/** *//**
* 關(guān)閉當(dāng)前word文檔
*
*/
public void closeDocument() {
if (doc != null ) {
Dispatch.call(doc, "Save" );
Dispatch.call(doc, "Close" , new Variant(saveOnExit));
doc = null ;
}
}
/** *//**
* 關(guān)閉全部應(yīng)用
*
*/
public void close() {
closeDocument();
if (word != null ) {
Dispatch.call(word, "Quit" );
word = null ;
}
selection = null ;
documents = null ;
}
/** *//**
* 打印當(dāng)前word文檔
*
*/
public void printFile() {
if (doc != null ) {
Dispatch.call(doc, "PrintOut" );
}
}
public static void main(String args[]) throws Exception {
MSWordManager msWordManager = new MSWordManager( true );
msWordManager.createNewDocument();
msWordManager.insertText( "aaaaaaaaaaaaaaaaaaaaa" );
msWordManager.moveEnd();
msWordManager.close();
}
}
新建一個類T,來測試一下jacob是否能用,代碼如下
package
com.test;
public class T {
public static void main(String[] args) {
// TODO Auto-generated method stub
MSWordManager ms= new MSWordManager( true );
//生成一個MSwordManager對象,并且設(shè)置顯示W(wǎng)ord程序
ms.createNewDocument();
//創(chuàng)建一個新的.doc文件
ms.insertText( "Test jacob" );
//插入文本
ms.save( "c://1.doc" );
//保存.doc文件
ms.close();
ms.closeDocument();
}
}
public class T {
public static void main(String[] args) {
// TODO Auto-generated method stub
MSWordManager ms= new MSWordManager( true );
//生成一個MSwordManager對象,并且設(shè)置顯示W(wǎng)ord程序
ms.createNewDocument();
//創(chuàng)建一個新的.doc文件
ms.insertText( "Test jacob" );
//插入文本
ms.save( "c://1.doc" );
//保存.doc文件
ms.close();
ms.closeDocument();
}
}
運行后C盤生成了1.doc文件,
這樣也是沒有實際意義,所以我們要加入數(shù)據(jù)庫。
數(shù)據(jù)庫依然是DB2 9.5 ,用戶名db2admin 密碼abc 表名admin
我在這個項目中添加了Hibernate框架,Java程序代碼如下
package
com.dao;
import java.util.List;
public class Test {
public static void main(String[] args) {
AdminDAO dao = new AdminDAO();
List list = dao.findAll();
MSWordManager ms= new MSWordManager( false );
ms.createNewDocument();
for ( int i=1;i<=list.size();i++){
Admin admin = (Admin)list.get(1);
ms.insertText(admin.getName());
ms.insertText( "本文章由jacob自動生成" );
ms.moveEnd();
}
ms.save( "c://1.doc" );
ms.closeDocument();
ms.close();
}
}
import java.util.List;
public class Test {
public static void main(String[] args) {
AdminDAO dao = new AdminDAO();
List list = dao.findAll();
MSWordManager ms= new MSWordManager( false );
ms.createNewDocument();
for ( int i=1;i<=list.size();i++){
Admin admin = (Admin)list.get(1);
ms.insertText(admin.getName());
ms.insertText( "本文章由jacob自動生成" );
ms.moveEnd();
}
ms.save( "c://1.doc" );
ms.closeDocument();
ms.close();
}
}
運行程序后,進入c盤,打開生成的1.doc文件。
這就是Java利用開源工具jacob操作Microsoft Word
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
